gpt4 book ai didi

python - 使用装饰器将字典插入 python 类

转载 作者:太空宇宙 更新时间:2023-11-04 02:14:37 25 4
gpt4 key购买 nike

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

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 类中。既然字典是不可调用的,那么这样的包装器将如何设计?

更新

感谢您对此的建设性反馈。一位 stack-overflow 用户正确地指出我没有解释为什么我想这样做。所以这里是:

  1. 我正在尝试构建一个框架,该框架基本上可以使用大量用户定义的函数并扩展现有类。所以我有一个类 A 和用户定义的函数 f_1, f_2, ..., f_n 其中我想注入(inject)类 A 以便此类 obj_a = A() 的实例可以调用这些函数,例如 obj_a.f_1()。我已经设法使用类似于上面代码片段的装饰器函数实现了这一点。
  2. 现在,每个用户定义的函数都有一些重复的代码,我认为如果我的基类 A 的所有实例都可以访问用户定义的字典,我可以取消这些代码。我实现这一目标的思考过程是尝试修改我现有的包装函数以将其添加到类中。但是,我知道字典是不可调用的,因此是个问题。

我希望这足够详尽。

更新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()

每个用户函数都包含一个常用字典的子集。为了利用这一点,我认为如果可以将其作为动态注入(inject)的 BaseClass 属性的一部分进行访问会很方便。

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_
...

为了合并它,我可能必须将 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)

这个解决方案有效,但也多少回答了我的问题,我想我可以说,当一个简单的函数可能实现这个时,我可能通过为此编写一个装饰器来过度设计我的解决方案。

但是,原始问题的一个方面仍然存在 - 这是一个好的方法吗?

最佳答案

你问问题的方式暗示你不太明白 python 如何使用对象引用。

装饰器并不意味着与不可调用的对象一起使用,所以它是澄清

accept the name of a class (not an object)

不是很清楚。您想要附加到类的内容没有区别 — 字典或函数,无论如何您只会操作抽象引用。

除此之外,看看这个片段:

def patcher(cls):
def wrapper(*args, **kwargs):
instance = cls(*args, **kwargs)
instance.payload = {'my': 'dict'}
return instance
return wrapper

@patcher
class A:
pass

它是否满足您的需求?

关于python - 使用装饰器将字典插入 python 类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52929082/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com