python在看到代码里有修饰符的时候,不太理解里面的流程,研究了很久,算是摸清楚里面的逻辑,在这里也记录一下
修饰符其实本质上应该算是一种回调函数
先看一段代码,最简单的修饰符
def callback(f):
print('called')
return f
@callback # 注册回调函数
def pp(x):
print('function exe')
return 2 * x
print(pp(3))
运行结果:
called
function exe
6
在定义pp函数的时候,前面加了个修饰符,这个修饰符本身也指向一个函数callback,整个语句的逻辑表现就是
调用pp函数的时候,其实是调用两个函数
pp(x) -> callback (pp) (x)
但是需要注意的是 callback(pp) 只在修饰符定义@callback的时候运行一次,也就是相当于注册回调函数,如下
def callback(f):
print('called')
return f
@callback # 注册回调函数
def pp(x):
print('function exe')
return 2 * x
运行结果:
called
后面实际调用pp函数的时候,是不会再运行callback(pp)的,如下
def callback(f):
print('called')
return f
@callback # 注册回调函数
def pp(x):
print('function exe')
return 2 * x
print(pp(3))
print(pp(4))
print(pp(5))
运行结果:
called
function exe
6
function exe
8
function exe
10
所以整个修饰符的核心在于callback的return值,相当于名义上调用函数,实际上是调用
callback(pp)运行后返回的函数
def callback(f):
print('called')
def call_inter(x):
print('call_inter')
return x
return call_inter
@callback # 注册回调函数
def pp(x):
print('function exe')
return 2 * x
print(pp(3))
print(pp(4))
运行结果:
called
call_inter
3
call_inter
4
这就可以看到 callback(pp)以后,return的函数实际上是又定义了一个内部函数call_inter,那么运行pp(x)的结果就相当于 callback(pp)(x) ,其中callback(pp) 指向的是 call_inter函数,所以就相当于call_inter(x),输出的''called''是只在注册过程中会打印一次,“call_inter”会在每次运行函数的时候都会输出
再看下一段代码,更能让大家理解一下
def callback():
print('called')
def call_inter(x):
print('call_inter')
return x
return call_inter
@callback() # 注册回调函数
def pp(x):
print('function exe')
return 2 * x
print(pp(3))
print(pp(4))
输出的结果:
called
call_inter
function exe
6
function exe
8
大家可以注意到callback函数没有参数了,同时修饰符也从@callback变成了 @callback()
所以整个的函数意义又变了,运行pp(x)就相当于 callback()(pp)(x),其中 callback()返回的是call_inter函数 ,那么 callback()(pp)就相当于 call_inter(pp), 可以看到call_inter(pp)返回的就是pp函数本身,输出的''called'',“call_inter” 都只在注册过程中会打印一次,而“function exe”会在每次运行函数的时候都会输出
所以修饰符是不是也没那么难理解了