python 装饰器


  • python装饰器就是用于拓展原来函数功能的一种函数,这个函数的特殊之处在于它的返回值也是一个函数,使用python装饰器的好处就是在不用更改原函数的代码前提下给函数增加新的功能。
  • 装饰器符号“@”属于语法糖,什么意思呢?就是说,我不按照@装饰器的语法要求来写,而是按照一般python的语法要求来写完全可以。那么用@装饰器的格式来写的目的就是为了书写简单方便

例子

假如我有一个函数,功能是计算两个数的和,

def sum(a, b):
print(a + b)

sum(2, 1)

现在要求增加一个功能,求完和之后再求差值。但是不能更改原来的函数。可以这样做:

def sum(a, b):
print(a + b)

def decorate(func):
def minus(a, b):
func(a, b)
print(a - b)
return minus

sum = decorate(sum)

sum(2, 1)

这里我们将 sum 函数作为参数传入 decorate 函数,并将返回值重新指向 sum,相当于装饰了 sum 函数。

为了简化这种操作,python 提供了一种语法糖。可以直接这样写:

def decorate(func):
def minus(a, b):
func(a, b)
print(a - b)
return minus

@decorate
def sum(a, b):
print(a + b)

sum(2, 1)

上面两处代码功能相同,其实 @decorate 就相当于 sum = decorate(sum)

多个装饰器

当多个装饰器修饰同一个函数时,先执行靠近函数的。

def dec1(func):  
print("1111")
def one():
print("2222")
func()
print("3333")
return one

def dec2(func):
print("aaaa")
def two():
print("bbbb")
func()
print("cccc")
return two

@dec1
@dec2
def test():
print("test test")

test()

#运行结果:
aaaa
1111
2222
bbbb
test test
cccc
3333

上面代码流程:

先执行 @dec2 ,即 test = two(test),同时输出 aaaa。
再执行 @dec1,即 test = one(test),同时输出 1111。

此时,函数 test 相当于执行了: test = one ( two ( test ) )

当执行到 test()时,运行函数从外到内,输出

2222    // one()
bbbb // two()
test test //test()
cccc // two()
3333 // one()

参考


https://mp.weixin.qq.com/s/KpveR377KifKJ7_drWxFGg