前言
多次见到@符,多次听到“装饰器”,“修饰函数”这个,之前也半知半解的学习了解过,但是又默默的忘记了,最近又遇到了,在这好好学习记录一下。
定义与用途
简单的讲,@是一个装饰器,针对函数,起调用传参的作用。是不是很抽象,很不好理解。下面慢慢讲:
@可以在模块或者类的定义层内对函数进行修饰,出现在函数定义的前一行,不允许和函数定义在同一行,一个修饰器就是一个函数,它将被修饰的函数作为参数,并返回修饰后的同名函数或其他可调用的东西。
装饰器符号@属于语法糖,即我不按照@装饰器的语法要求来写,而是按照一般python的语法要求来写完全可以。那么用@装饰器的格式来写的目的就是为了书写简单方便
装饰器的作用,装饰原有的函数(废话)。什么意思呢?比如有一个函数func(a, b),它的功能是求a,b的差值,我现在有一个需求,就是想对函数功能再装饰下,求完差值后再取绝对值,但是不能在func函数内部实现,这时候就需要装饰器函数了,比如func = decorate(func)函数,将func函数作为参数传递给decorate函数,由decorate来丰富func函数,丰富完成后再返回给func,此时func的功能就丰富了。
了解上述观点后,可以先不用@符号来写一个简单的装饰器
代码
def decorate(func):
def inner(a,b):
ret=func(a,b)
return abs(ret)
return inner
def sub(a,b):
return a-b
print(sub(3,4))
sub=decorate(sub)
print(sub(3,4))
结果
-1
1
对于sub = decorate(sub)的理解。最终是将inner的值传给sub ,此时执行sub(3, 4),其实是执行decorate中的inner,所以为1。
为了偷懒,将sub=decorate(sub)换为@decorate,并放在sub的定义面前,即:
代码
def decorate(func):
def inner(a,b):
ret=func(a,b)
return abs(ret)
return inner
@decorate
def sub(a, b):
return a-b
print(sub(3,4))
结果
1
进阶一点
先看一段代码
代码
def funA(desA):
print("It's funA")
def funB(desB):
print("It's funB")
@funA
def funC():
print("It's funC")
结果
It's funA
分析
@funA 修饰函数定义def funC(),将funC()赋值给funA()的形参。执行的时候由上而下,先定义funA、funB,然后运行funA(funC())。此时desA=funC(),然后funA()输出‘It’s funA’。
再看一段
代码
def funA(desA):
print("It's funA")
def funB(desB):
print("It's funB")
@funB
@funA
def funC():
print("It's funC")
结果
It's funA
It's funB
分析
@funB 修饰装饰器@funA,@funA 修饰函数定义def funC(),将funC()赋值给funA()的形参,再funA(funC())赋值给funB()。执行的时候由上而下,先定义funA、funB,然后运行funB(funA(funC()))。此时desA=funC(),然后funA()输出‘It’s funA’;desB=funA(funC()),然后funB()输出‘It’s funB’。
参考
https://www.jb51.net/article/158533.htm