如何装饰从文件导入的所有函数?
How can I decorate all functions imported from a file?
我创建了很多函数,它们被分成不同的文件,现在我想为所有这些函数应用相同的装饰器,而无需修改文件,也无需一个一个地应用装饰器。
我试过使用delnan写的this explanation,但是导入函数没有成功。
关于装饰器,每次使用函数参数和值执行 class 中的函数时,它必须更新列表,就像 我问的那样。
有什么建议可以帮助我解决这个问题吗?
谢谢
一点自省(dir()
) and dynamic look-up with getattr()
and setattr()
.
首先,我们遍历在模块和 check for objects that look like functions 中找到的所有名称。之后,我们只需将旧函数重新分配给装饰过的函数即可。
main.py:
import types
import functools
def decorate_all_in_module(module, decorator):
for name in dir(module):
obj = getattr(module, name)
if isinstance(obj, types.FunctionType):
setattr(module, name, decorator(obj))
def my_decorator(f):
@functools.wraps(f)
def wrapper(*args, **kwargs):
print(f)
return f(*args, **kwargs)
return wrapper
import mymod1
decorate_all_in_module(mymod1, decorator)
mymod1.py:
def f(x):
print(x)
def g(x, y):
print(x + y)
输出:
<function f at 0x101e309d8>
2
<function g at 0x101e30a60>
7
如果您使用明星进口 (from mymod import *
),过程不会那么顺利。原因很简单——因为所有的名字都在一个大袋子里,而且它们的来源没有区别,你需要很多额外的技巧来找到你想要修补的东西。但是,这就是我们使用名称空间的原因 - because they are one honking great idea.
我创建了很多函数,它们被分成不同的文件,现在我想为所有这些函数应用相同的装饰器,而无需修改文件,也无需一个一个地应用装饰器。
我试过使用delnan写的this explanation,但是导入函数没有成功。
关于装饰器,每次使用函数参数和值执行 class 中的函数时,它必须更新列表,就像
有什么建议可以帮助我解决这个问题吗? 谢谢
一点自省(dir()
) and dynamic look-up with getattr()
and setattr()
.
首先,我们遍历在模块和 check for objects that look like functions 中找到的所有名称。之后,我们只需将旧函数重新分配给装饰过的函数即可。
main.py:
import types
import functools
def decorate_all_in_module(module, decorator):
for name in dir(module):
obj = getattr(module, name)
if isinstance(obj, types.FunctionType):
setattr(module, name, decorator(obj))
def my_decorator(f):
@functools.wraps(f)
def wrapper(*args, **kwargs):
print(f)
return f(*args, **kwargs)
return wrapper
import mymod1
decorate_all_in_module(mymod1, decorator)
mymod1.py:
def f(x):
print(x)
def g(x, y):
print(x + y)
输出:
<function f at 0x101e309d8>
2
<function g at 0x101e30a60>
7
如果您使用明星进口 (from mymod import *
),过程不会那么顺利。原因很简单——因为所有的名字都在一个大袋子里,而且它们的来源没有区别,你需要很多额外的技巧来找到你想要修补的东西。但是,这就是我们使用名称空间的原因 - because they are one honking great idea.