Python 使用decorator修补模块中的所有函数
我有一个包含很多函数的python模块,我想为所有函数应用一个装饰器。 有没有一种方法可以通过monkey patching对所有函数进行修补,从而对每个函数应用此装饰器,而无需在应用装饰器的行上进行复制粘贴 换言之,我想替换这个:Python 使用decorator修补模块中的所有函数,python,Python,我有一个包含很多函数的python模块,我想为所有函数应用一个装饰器。 有没有一种方法可以通过monkey patching对所有函数进行修补,从而对每个函数应用此装饰器,而无需在应用装饰器的行上进行复制粘贴 换言之,我想替换这个: @logging_decorator(args) func_1(): pass @logging_decorator(args) func_2(): pass @logging_decorator(args) func_3(): pass @lo
@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
我真的不确定这是个好主意,毕竟 话虽如此,类似这样的东西应该可以工作,使用来找到模块的哪些成员可以被修饰,并使用来操作模块的内容
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()
我不会漂亮的。。。但是可以在定义之后使用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)')
我不知道你会怎么做,但我认为你不应该。最好是直言不讳。查找/替换应该有助于解决必须为每个函数键入它的问题。不是在这一点上,而是当您
导入它时,您可以迭代模块公开的名称并从那里修补它们。您尝试过吗?“这看起来有点凌乱,”MarcelWilson说,“我理解,但这不是我唯一需要修补的地方。”。“没有一门课可以添加一个mixin或类似的东西来做得更像elegat的方式。”Paul我明白你的意思,并且承认这是一个聪明的主意。我担心,对于下一个代码维护者来说,结果会变得复杂/混乱。我明白了,有时候聪明并不总是更好。看起来和我需要的很相似!这里有没有办法把args传递给decorator?因为实际上@logging\u decorator(args)
需要args来跟踪这些跟踪。带参数的decorator被实现为返回一个包装其参数的标准decorator-因此使用decorator模块(module\u to\u wrap,logging\u decorator(args))
应该可以工作。我当前方法的局限性是,如果logging\u decorator
存在于您试图包装的模块中,那么decoration\u module
将尝试装饰它,这可能是不好的。(decoration_module
尝试不修饰decorator,但由于使用参数进行修饰会动态生成新函数,因此这不起作用。)因此,实际上,我的日志修饰器存在于其他包中,因此我相信这不是问题。非常感谢。