向 Python 装饰器为 运行 的模块添加属性

Add an attribute to the module in which a Python decorator is running

我想写一个 Python 装饰器,它向装饰器是 运行 的模块添加一个属性,即

@procedure
def whatever(arg1, arg2):
    # do things
    return

应该将属性 attr 添加到 whatever 所在的模块。我试过如下编写装饰器 procedure(在另一个文件中定义)

def procedure(fn):
    global attr
    attr = SomeClass()
    return fn

attr 被添加到定义了 procedure 的模块中,而不是添加到 procedure 运行的模块中。还有其他方法吗?

假设您想标记 一个函数,这样定义它的模块的某些用户将能够知道它属于某个函数类别。你可以像这样写一个简单的装饰器:

def special(fn):
    globals().setdefault("__specials__", set()).add(fn)
    return fn

然后你可以写一个使用这个装饰器的模块,像这样:

"""Module 'has_specials'"""
def regular():
    return "meh"

@special
def important():
    return "wow!"

@special
def bigshot():
    return "HA"

这可以被另一个模块使用,如下所示:

import has_specials

if hasattr(has_specials, "__specials__"):
    for fn in has_specials.__specials__:
        print("%-20s: %s" % (fn.__name__, fn))

上面的代码将导入模块,并列出 special 函数:

important           : <function important at 0x000002435FD51488>
bigshot             : <function bigshot at 0x000002435FD51510>