You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python装饰器导致PLUGINS字典无法持久化存储函数地址的问题

问题解答

1. 为什么会打印两次空字典?

这两次空字典的打印发生在函数定义阶段,而非调用say_hello的时候。当你用@register装饰函数时,装饰器register会立即执行(此时函数还未被调用):

  • 定义say_hello时,register(say_hello)被触发,内部打印此时仍为空的PLUGINS。
  • 定义be_awesome时,register(be_awesome)被触发,再次打印空的PLUGINS。
    这就是两次空字典的来源。

2. 为什么退出wrapper后PLUGINS中的条目消失?

根据你提供的代码,这种情况本不应该发生。当你调用say_hello('Addam')时,实际执行的是wrapper函数:

  • wrapper内部会将原始的say_hello函数存入PLUGINS,此时PLUGINS会包含该条目。
  • 除非你在代码未展示的部分重新初始化了PLUGINS,否则这个条目会一直保留。

不过从代码逻辑来看,你的意图应该是在装饰函数时完成注册,而非等到函数被调用时才注册。当前代码把注册逻辑放在wrapper内部,导致只有调用函数时才会将函数加入PLUGINS。如果要实现装饰阶段注册,需将注册逻辑移到register函数内部、wrapper之外:

PLUGINS = dict()

def register(func):
    """Register a function as a plug-in"""
    PLUGINS[func.__name__] = func
    print(PLUGINS)  # 装饰函数时就会打印包含当前函数的字典
    
    def wrapper(*args, **kwargs):
        print('hello', func.__name__)
        return func(*args, **kwargs)
    
    return wrapper

@register
def say_hello(name):
    return f"Hello {name}"

@register
def be_awesome(name):
    return f"Yo {name}, together we are the awesomest!"

print(say_hello('Addam'))
print(PLUGINS)  # 此时会包含两个函数条目

修改后,say_hello和be_awesome在定义时就会被立即加入PLUGINS,无需等到函数调用。

内容的提问来源于stack exchange,提问作者Santiago Rodríguez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 05:14:54