Python多个装饰器的调用顺序与执行流程解析

蓝鲸
蓝鲸
发布时间:2026-10-13 | 4人浏览过
原创

本文深入解析Python中多个装饰器的应用机制。明确区分装饰器的应用顺序(从里到外)与函数的实际执行顺序(从外到内)。通过具体代码示例,逐步拆解装饰器层层包裹的过程,展示inner函数的嵌套关系及print语句的输出逻辑,帮助开发者准确理解并调试复杂装饰器场景。

多个装饰器的应用与执行顺序

在Python编程中,单个函数通常只需应用一个装饰器,但在复杂场景下,可能会遇到两个或更多装饰器同时作用于同一函数的情况。理解多个装饰器的工作机制至关重要:装饰器的应用(即包裹函数)顺序遵循从里到外的就近原则,而最终调用被装饰函数时,执行流程则是从外到里的远端原则。

装饰器执行流程代码示例

以下通过具体代码样例进行说明:

装饰器定义与调用代码


def func1(func):
  print(1)
  def inner1(*args, **kwargs):
    print(2)
    res = func(*args, **kwargs)
    print(3)
    return res
  print(4)
  return inner
 
def func2(func):
  print(5)
  def inner2(*args, **kwargs):
    print(6)
    res = func(*args, **kwargs)
    print(7)
    return res
  print(8)
  return inner<br data-filtered="filtered">
@func1
@func2
def go():
  print("running..")<br data-filtered="filtered">go()

实际上,函数go的执行本质可以拆解为一系列嵌套赋值过程,具体逻辑如下所示:

  • 首先执行a=func2(go),此时a指向inner2函数的地址。由于func2内部包含print(5)和print(8),因此控制台首先输出5和8这两个值。
  • 接着执行b=func1(a),此时b指向inner1函数的地址。同样,由于func1内部包含print(1)和print(4),控制台随后输出1和4这两个值。
  • 最后执行b(),即调用inner1函数。在inner1内部,func参数指向inner2;当执行inner2时,其func参数指向原始定义的go函数。因此,随着调用深入,依次输出2、6、running、7、3。

综上所述,整个调用过程等价于表达式:b(func1(func2(go)))()。

为了更清晰地展示这一过程,我们可以将其等效转换为如下逐步赋值的效果:

第一步,a=func2(go)。此时a存储的是inner2函数的地址。由于func2执行时会打印5和8,因此输出内容为5和8两个值。

第二步,go=func1(a)。注意这里的go是一个新变量,它不再指向原始函数,而是指向inner1函数的地址。由于func1执行时会打印1和4,因此输出内容为1和4两个值。

第三步,执行go()。此时调用的是inner1函数,其内部的func参数指向inner2;而inner2内部的func参数指向最初定义的go函数。因此,最终输出的内容依次为2、6、running、7、3。

这一过程等价于表达式:go(func1(func2(go)))()。

以下是实际运行测试的结果:

实际运行输出结果


C:\Python27\python.exe D:/code-program/lianxi-test/route.py
5
8
1
4
2
6
running..
7
3
 
Process finished with exit code 0

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表