为完整模块定义Python装饰器
我有一个包含很多函数的模块(超过25个)。我想为这些函数中的每一个添加一个公共装饰函数。通常的做法是在每个函数上方添加@decorator行,但我想知道是否有更好的方法?也许我可以在模块顶部声明一个全局装饰器或其他什么 请注意,由于我使用的是其他人的代码,因此我希望尽量减少更改的行数,因此修改模块对我来说并不理想为完整模块定义Python装饰器,python,decorator,Python,Decorator,我有一个包含很多函数的模块(超过25个)。我想为这些函数中的每一个添加一个公共装饰函数。通常的做法是在每个函数上方添加@decorator行,但我想知道是否有更好的方法?也许我可以在模块顶部声明一个全局装饰器或其他什么 请注意,由于我使用的是其他人的代码,因此我希望尽量减少更改的行数,因此修改模块对我来说并不理想 谢谢。如果您的装饰者被称为my\u装饰者 ### Decorate all the above functions import types for k,v in globals().
谢谢。如果您的装饰者被称为
my\u装饰者
### 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)
我认为,整体应用一个装饰器(decorator)是一个不好的主意,这样你就不知道你会去哪里寻找关于函数的信息(在它的定义上)。显式比隐式好,所有这些 如果您希望在不修改第三方代码的情况下将decorator应用于某些第三方模块的函数,我将这样做:
# 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))
然后在其他地方使用这些函数,方法是从我的\u包装器\u模块中执行,导入一些\u func\u 2
,等等
对我来说,这有以下好处:
我的\u包装器\u模块
,看看我在调用什么,并且我没有使用未修饰的函数版本my_wrapper_module
可以清楚地看出,导出的函数是什么,它们最初来自某些_module
,并且它们都应用了相同的decorator某些_模块的代码都不会受到无声和莫名其妙的影响;如果第三方代码是多个模块,这一点可能特别重要
但是,如果您试图入侵第三方库,从而影响内部调用,那么这并不是您想要的。这是非常安全的-实际上我在实际项目中使用了类似的方法。谢谢您的回答!这对我来说确实有效,但有一个小问题,它还添加了我导入的函数(如“from copy import deepcopy”)。。。有没有办法跳过这些函数,只添加我自己在模块顶层定义的函数。。。谢谢将“vars(othermodule)[k]=my_decorator(v)”替换为“setattr(othermodule,k,my_decorator(v)),以避免可能出现的“'dictproxy'对象不支持项分配”注意,这会使读者更难意识到函数是经过修饰的。我同意有时候这是一个很好的方法,但它有点违背了“显式优于隐式”的指导原则正在创建
wrapper\u模块
。顺便说一句,我已经删除了我的答案(因为@gnibbler更完整,并且有正确的函数类型检查)。谢谢你的答案。我做了那件事following@reclosedev干杯,我现在已经删除了对你答案的引用。