【转载请标明出处】https://blog.csdn.net/mingtiannihaoabc/article/details/119064605
- 简述
- 当有多个装饰器叠加时,从最靠近被装饰函数的装饰器开始执行。
- 就算被装饰函数不被调用,只要程序模块开始被运行,那么装饰器中的逻辑也会开始执行,这个和闭包有关。
- 闭包知识补充(大白话)
在一个内部函数中,对外部作用域的变量进行引用,(并且一般外部函数的返回值为内部函数),那么内部函数就被认为是闭包。 - 之前写过的两篇关于装饰器的文章如下
python装饰器的简单运用 扩展Python装饰器的功能 - 完整的看了这篇文章,相信你对多个装饰器叠加的时候,他们的执行顺序有一个深刻以及清晰的理解了.
- 不带参数的装饰器
from functools import wraps
def register1(func):
print('running register1 {}'.format(func))
@wraps(func)
def test(*args, **kwargs):
print('register1 test begin')
result = func(*args, **kwargs)
print('register1 test over')
return result
return test
def register2(func):
print('running register2 {}'.format(func))
@wraps(func)
def test(*args, **kwargs):
print('register2 test begin')
result = func(*args, **kwargs)
print('register2 test over')
return result
return test
def register3(func):
print('running register3 {}'.format(func))
@wraps(func)
def test(*args, **kwargs):
print('register3 test begin')
result = func(*args, **kwargs)
print('register3 test over')
return result
return test
@register1
@register2
@register3
def t1():
print('running f1()')
t1()
执行结果如下
@register1
@register2
@register3
def t1():
print('running f1()')
t1()
def t1():
print('running f1()')
t1 = register1(register2(register3(t1)))
t1()
运行结果如下
- 带参数的装饰器
from functools import wraps
def w1(wp1):
print(wp1)
def f1(fn):
print("f1")
@wraps(fn)
def inner(*args, **kwargs):
print("begin login f1")
result = fn(*args, **kwargs)
print("login f1 is over")
return result
return inner
return f1
def w2(wp2):
print(wp2)
def f2(fn):
print("f2")
@wraps(fn)
def inner(*args, **kwargs):
print("begin login f2")
result = fn(*args, **kwargs)
print("login f2 is over")
return result
return inner
return f2
def w3(wp2):
print(wp2)
def f3(fn):
print("f3")
@wraps(fn)
def inner(*args, **kwargs):
print("begin login f3")
result = fn(*args, **kwargs)
print("login f3 is over")
return result
return inner
return f3
@w1('w1111')
@w2('w2222')
@w3('w3333')
def main2():
print("main1")
print("main1 over")
main()
@w1('w1111')
@w2('w2222')
@w3('w3333')
def main2():
print("main1")
print("main1 over")
main2()
等价于如下代码块,这也验证了就算被装饰函数不被调用,只要程序模块开始被运行,那么装饰器中的逻辑也会开始执行
def main2():
print("main1")
print("main1 over")
main2 = w1('w1111')(w2('w2111')(w3('w3111')(main2)))
main2()
他们的执行结果都是如下结果
|