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

Python中装饰器与被装饰函数同名时的语法运行机制问询

装饰器与被装饰函数同名的执行逻辑解析

先看你给出的代码:

def say_hello(func):
    def wrapper(x):
        return x.upper()
    return wrapper

@say_hello
def say_hello(string):
    return string

say_hello('hello')

核心原因:装饰器语法的执行顺序

Python的@装饰器名语法是个语法糖,它的执行逻辑是按步骤来的,根本不会出现“被装饰函数刚定义就覆盖装饰器”的情况:

  1. 先完整定义被装饰的函数(也就是第二个say_hello),此时这个函数只是临时存在,还没替换全局命名空间里的say_hello。
  2. 紧接着调用当前全局里的装饰器函数(第一个say_hello),把刚定义的被装饰函数作为参数传进去。
  3. 最后把装饰器返回的结果(也就是wrapper函数)重新赋值给全局的say_hello,这时候才完成对原装饰器的覆盖。

具体步骤拆解

  • 第一步:执行第一个def say_hello(func),全局命名空间里存入了这个装饰器函数。
  • 第二步:遇到@say_hello,Python先执行下面的def say_hello(string),生成被装饰的函数对象,但这时候它还没覆盖全局的say_hello。
  • 第三步:调用全局的say_hello(装饰器),把刚生成的被装饰函数传进去,得到wrapper函数。
  • 第四步:把wrapper赋值给全局的say_hello,这时候原装饰器才被替换掉。

关于命名空间的疑问

装饰器语法没有独立的命名空间,整个过程都在全局命名空间里完成。关键就是被装饰函数的定义和全局变量的覆盖是两个分开的动作:先定义函数(此时全局say_hello还是装饰器),用装饰器处理它,最后才把处理后的结果覆盖全局变量。

所以程序执行装饰器逻辑时,能正常访问到第一个say_hello,因为这时候第二个say_hello还没完成对全局变量的覆盖。

内容的提问来源于stack exchange,提问作者ddc

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 01:32:40