我有一个具有很多功能的python模块,我想为所有功能应用一个装饰器。有没有一种方法可以通过猴子绘制来修补所有这些,以将此装饰物应用于每个功能,而无需在应用装饰器的线上抄写?
换句话说,我想替换:
@logging_decorator(args)
func_1():
pass
@logging_decorator(args)
func_2():
pass
@logging_decorator(args)
func_3():
pass
@logging_decorator(args)
func_n():
pass
与此:
patch_func():
# get all functions of this module
# apply @logging_decorator to all (or not all) of them
func_1():
pass
func_2():
pass
func_3():
pass
func_n():
pass
我真的不确定这是一个好主意。毕竟,显式比隐式好。
话虽如此,类似的事情应该起作用,使用Inspect查找可以装饰模块的哪个成员并使用__dict__
操纵模块的内容。
import inspect
def decorate_module(module, decorator):
for name, member in inspect.getmembers(module):
if inspect.getmodule(member) == module and callable(member):
if member == decorate_module or member == decorator:
continue
module.__dict__[name] = decorator(member)
示例用法:
def simple_logger(f):
def wrapper(*args, **kwargs):
print("calling " + f.__name__)
f(*args, **kwargs)
return wrapper
def do_something():
pass
decorate_module(sys.modules[__name__], simple_logger)
do_something()
i不会漂亮...但是您可以在定义后使用dir()列出所有功能。然后,我想不出没有包装器功能的方法来修补它们。
def patched(func):
@logging_decorator
def newfunc(*args, **kwargs):
return func(*args, **kwargs)
return newfunc
funcs=[f in dir() if not '__' in f]
for f in funcs:
exec(f+'=patched(f)')