我有一个包含很多函数(超过25个)的模块。我想为这些函数中的每一个添加一个通用的装饰器函数。正常的做法是在每个函数上添加一个@decorator行,但我想知道是否有更好的方法来做到这一点?也许我可以在模块的顶部或其他地方声明一个全局装饰器?为完整模块定义Python装饰器
请注意,由于我正在使用别人的代码,因此我想尽量减少更改的行数,因此修改模块对我来说并不理想。
谢谢。
我有一个包含很多函数(超过25个)的模块。我想为这些函数中的每一个添加一个通用的装饰器函数。正常的做法是在每个函数上添加一个@decorator行,但我想知道是否有更好的方法来做到这一点?也许我可以在模块的顶部或其他地方声明一个全局装饰器?为完整模块定义Python装饰器
请注意,由于我正在使用别人的代码,因此我想尽量减少更改的行数,因此修改模块对我来说并不理想。
谢谢。
如果你的装饰被称为my_decorator
### Decorate all the above functions
import types
for k,v in globals().items():
if isinstance(v, types.FunctionType):
globals()[k] = my_decorator(v)
你也该将其导入
import othermodule
import types
for k,v in vars(othermodule).items():
if isinstance(v, types.FunctionType):
vars(othermodule)[k] = my_decorator(v)
我想申请一个装饰后应用到模块EN-集体这样,这不是很明显,你将去查找有关函数(在其定义)通常是一个坏主意。显式优于隐式,以及所有这些。
如果你想装饰适用于某些第三方模块的功能,而无需修改第三方代码,这里是我会怎么做:
# my_wrapper_module.py
import some_module
import functools
def some_decorator(func):
@functools.wraps(func):
def wrapper(*args, **kwargs):
...
return wrapper
FUNCTION_NAMES = [
'some_func_1',
'some_func_2',
'some_func_3',
...
]
for name in FUNCTION_NAMES:
globals()[name] = some_decorator(getattr(some_module, name))
然后做from my_wrapper_module import some_func_2
其他地方使用这些功能等
对于我来说,这具有以下优点:
my_wrapper_module
看我打电话有什么明确的,那我不使用的功能未修饰版本my_wrapper_module
已出口哪些功能,他们最初来自some_module
,并且它们都具有相同的装饰应用some_module
并不能直接默默莫名其妙地影响任何代码;如果第三方代码的多个模块这可能是特别重要的,但如果你正在试图做的是破解一个第三方库,这样内部呼叫被影响,那么这是不是你想要的。
就像你创建'wrapper_module'的想法一样。顺便说一下,我删除了我的答案(因为@ gnibbler的更完整,并且对函数类型有正确的判断)。 – reclosedev
感谢您的回答。我做了以下 – Rajat
@reclosedev干杯,我已经删除了对你的答案的参考。 – Ben
这是非常安全的 - 我真的在一个真实的项目中使用这样的东西。 – jsbueno
感谢您的回答!这对我有用,但有一个小问题,它还添加了我导入的函数(如“从复制导入deepcopy”)...是否有一种方法可以跳过这些函数,只添加I我自己定义在模块的顶层? ... 谢谢! – Rajat
为了避免可能的''dictproxy'对象不支持项目分配'替换“vars(othermodule)[k] = my_decorator(v)”“setattr(othermodule,k,my_decorator(v))” – user2426679