【问题标题】:How can I decorate all functions imported from a file?如何装饰从文件导入的所有函数?
【发布时间】:2017-01-04 04:35:32
【问题描述】:

我已经创建了许多功能,这些功能被划分到不同的文件中,现在我想为所有功能应用相同的装饰器,而不需要修改文件,也不需要一个一个地应用装饰器。

我试过用delnan写的this explanation,但是导入函数没有成功。

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

有什么建议可以帮助我解决这个问题吗? 谢谢

【问题讨论】:

  • 你是如何进行导入的?您是在做模块,还是在做个别功能或from foo import * 等...
  • 它们只是函数还是文件中类的方法?
  • 导入就像from modules import module1 一样完成,它们只是文件内部的函数。

标签: python wrapper python-decorators


【解决方案1】:

一点点内省 (dir()) 和 getattr()setattr() 的动态查找。

首先我们遍历模块和check for objects that look like functions 中找到的所有名称。之后,我们只需将旧功能重新分配给修饰过的功能。

ma​​in.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

【讨论】:

  • 感谢您的帮助,它运行良好。事实上,我问这个问题是为了完成我问过的another question。我以为我可以从中解决我的问题,但事实并非如此。每次运行导入类中的某些函数时,我希望我的装饰器保存参数和函数名。你能帮我解决这个新主题吗?
  • 你想装饰类的所有方法吗?过程非常相似,您执行dir(class) 并寻找方法而不是函数。我很确定您可以根据上面的模板自己弄清楚。
  • 好的,非常感谢。我使用 python 作为免费工具来代替 Matlab,直到现在我只将它用作数值工具。我看到我还有很多东西要学,但没有什么可以带走我学习它的意愿。再次感谢您。
猜你喜欢
  • 1970-01-01
  • 2011-06-24
  • 2021-04-14
  • 2018-09-11
  • 2021-04-16
  • 2020-08-22
  • 2014-11-07
  • 1970-01-01
  • 2020-09-20
相关资源
最近更新 更多