为完整模块定义Python装饰器

为完整模块定义Python装饰器,python,decorator,Python,Decorator,我有一个包含很多函数的模块(超过25个)。我想为这些函数中的每一个添加一个公共装饰函数。通常的做法是在每个函数上方添加@decorator行,但我想知道是否有更好的方法?也许我可以在模块顶部声明一个全局装饰器或其他什么 请注意,由于我使用的是其他人的代码,因此我希望尽量减少更改的行数,因此修改模块对我来说并不理想 谢谢。如果您的装饰者被称为my\u装饰者 ### Decorate all the above functions import types for k,v in globals().

我有一个包含很多函数的模块(超过25个)。我想为这些函数中的每一个添加一个公共装饰函数。通常的做法是在每个函数上方添加@decorator行,但我想知道是否有更好的方法?也许我可以在模块顶部声明一个全局装饰器或其他什么

请注意,由于我使用的是其他人的代码,因此我希望尽量减少更改的行数,因此修改模块对我来说并不理想


谢谢。

如果您的装饰者被称为
my\u装饰者

### Decorate all the above functions
import types
for k,v in globals().items():
    if isinstance(v, types.FunctionType):
        globals()[k] = my_decorator(v)
您还可以在导入模块后将其应用于该模块

import othermodule
import types
for k,v in vars(othermodule).items():
    if isinstance(v, types.FunctionType):
        vars(othermodule)[k] = my_decorator(v)

我认为,整体应用一个装饰器(decorator)是一个不好的主意,这样你就不知道你会去哪里寻找关于函数的信息(在它的定义上)。显式比隐式好,所有这些

如果您希望在不修改第三方代码的情况下将decorator应用于某些第三方模块的函数,我将这样做:

# my_wrapper_module.py

import some_module
import functools

def some_decorator(func):
    @functools.wraps(func):
    def wrapper(*args, **kwargs):
        ...
    return wrapper

FUNCTION_NAMES = [
    'some_func_1',
    'some_func_2',
    'some_func_3',
    ...
]

for name in FUNCTION_NAMES:
    globals()[name] = some_decorator(getattr(some_module, name))
然后在其他地方使用这些函数,方法是从我的\u包装器\u模块中执行
,导入一些\u func\u 2
,等等

对我来说,这有以下好处:

  • 无需修改第三方源文件
  • 从调用站点可以清楚地看到,我应该查看
    我的\u包装器\u模块
    ,看看我在调用什么,并且我没有使用未修饰的函数版本
  • my_wrapper_module
    可以清楚地看出,导出的函数是什么,它们最初来自
    某些_module
    ,并且它们都应用了相同的decorator
  • 任何直接导入
    某些_模块的代码都不会受到无声和莫名其妙的影响;如果第三方代码是多个模块,这一点可能特别重要

  • 但是,如果您试图入侵第三方库,从而影响内部调用,那么这并不是您想要的。

    这是非常安全的-实际上我在实际项目中使用了类似的方法。谢谢您的回答!这对我来说确实有效,但有一个小问题,它还添加了我导入的函数(如“from copy import deepcopy”)。。。有没有办法跳过这些函数,只添加我自己在模块顶层定义的函数。。。谢谢将“vars(othermodule)[k]=my_decorator(v)”替换为“setattr(othermodule,k,my_decorator(v)),以避免可能出现的“'dictproxy'对象不支持项分配”注意,这会使读者更难意识到函数是经过修饰的。我同意有时候这是一个很好的方法,但它有点违背了“显式优于隐式”的指导原则​​正在创建
    wrapper\u模块
    。顺便说一句,我已经删除了我的答案(因为@gnibbler更完整,并且有正确的函数类型检查)。谢谢你的答案。我做了那件事following@reclosedev干杯,我现在已经删除了对你答案的引用。