Py学习  »  Python

使用decorator将字典插入python类

cyberbeast • 6 年前 • 1771 次点击  

我试图设计一个包装器,它可以接受类(不是对象)的名称,并在类的每个实例中插入一个字典。下面是我在包装现有函数时如何实现这一点的片段。

def insert_fn_into_class(cls):
    """Decorator function that consumes a function and inserts it into the cls class."""
    def decorator(func):
        @wraps(func)
        def wrapper(self, *args, **kwargs):
            return func(*args, **kwargs)
        setattr(cls, f'prefix_{func.__name__}', wrapper)

    return decorator

如何使用类似的模板来修饰字典并将其插入cls类。既然字典是不可调用的,那么如何设计这样的包装器呢?

更新

感谢您对此的建设性反馈。 一位堆栈溢出用户正确地指出,我未能解释为什么要这样做。所以说:

  1. 我正在尝试构建一个框架,它实际上可以使用一堆用户定义的函数并扩展现有的类。所以我有一节课 A ,以及用户定义的函数 f_1 , f_2 f_n 我想把它注入课堂 这样类的一个实例 obj_a = A() 可以调用以下函数 obj_a.f_1() . 我使用了一个类似于上面代码片段的decorator函数来实现这一点。
  2. 现在,每个用户定义的函数都有一些重复的代码,如果基类的所有实例 可以访问用户定义的词典。我实现这一点的思路是尝试修改现有的包装函数,将其添加到类中。然而,我知道字典是不可调用的,因此,这个问题。

我希望这足够详细。

更新2

看来还有进一步细化的余地。下面是一个例子,说明我前面描述的各种组件是什么样子的。

module_a.py

class BaseClass():
    def __init__(self):
        ...

    def base_class_method(self):
        ...

    def run(self):
        getattr(self, 'prefix_user_fn_1')()

def extend(cls=BaseClass):
    def decorator(func):
        def wrapper(self, *args, **kwargs):
            return func(*args, **kwargs)
        setattr(cls, f'prefix_{func.__name__}', wrapper)
    return decorator

user_defined_functions.py

from module_a import BaseClass, extend

@extend()
def user_fn_1():
    dict_ = {'a':'b', 'c':'d'}
    ...

@extend()
def user_fn_2():
    dict_ = {'my':'dict', 'c':'d'}
    ...

main.py

from module_a import BaseClass

b = BaseClass()
b.run()

每个用户函数都包含一个常用字典的子集。为了利用这一点,我认为如果这可以作为动态注入的基类属性的一部分来访问,那将是很方便的。

modified_user_defined_functions.py

# THIS WILL NOT WORK FOR OBVIOUS REASONS
from module_a import BaseClass, extend, common_config, insert_config_into_class

# @common_config ?? Is this even a good idea?
dict_ = {'my':'dict', 'a':'b', 'c':'d'}
insert_config_into_class(BaseClass, dict_)

@extend()
def user_fn_1(self):
    print(self.dict_)
    # do something with self.dict_
    ...

若要合并此项,我可能必须将run方法更改为 BaseClass 像这样:

modified_module_a.py

...
class BaseClass():
    ...

    def run(self):
        getattr(self, 'prefix_user_fn_1')(self)

更新3-潜在解决方案

def shared_config(data, cls=BaseClass):
    setattr(cls, 'SHARED_DICT', data)

这个解决方案是可行的,但也在一定程度上回答了我的问题,我想我可以说,当一个简单的函数可能实现这一点时,我可能通过为此编写一个decorator来过度设计我的解决方案。

然而,最初问题的一个方面仍然存在——这是一个好办法吗?

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/40014
 
1771 次点击  
文章 [ 2 ]  |  最新文章 6 年前