如何装饰从文件导入的所有函数?

时间:2016-08-27 18:19:57

标签: python wrapper python-decorators

我创建了许多分为不同文件的函数,现在我想为所有文件应用相同的装饰器而不修改文件而不逐个应用装饰器。

我尝试使用delnan编写的this explanation,但导入的函数没有成功。

关于装饰器,每次使用函数参数和值执行类中的函数时,它必须更新列表,就像我问的this other question一样。

有任何建议可以帮我解决这个问题吗? 感谢

1 个答案:

答案 0 :(得分:5)

使用dir()getattr()进行一些内省(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