作者最近正在看廖老师的python教程 python学习(廖雪峰)
关于装饰器部分,总有一些思路不是很清晰的地方,这里写出来,希望能理顺下思路。
先看装饰器在python中的使用(这里直接引用廖老师的教程):
def log(func):
def wrapper(*args, **kw):
print('This is log')
return func(*args, **kw)
return wrapper
@log
def now():
print('world peace')
本来调用now()的输出应是'world peace',但现在的输出是'This is log \n world peace'
用法虽是如此,但具体怎么理解过程?
我觉得有以下几点:
1.one
# function-1
def now(x,*args,**kw):
print('world peace')
# function-2
def wrapper(*args,**kw):
return now(*args,**kw)
如果这样定义的话,那么function-1和function-2是等价的,相当于wrapper = now,可以发现now(..)和wrapper(..)的执行结果是一致的
这样的话,如果修改一下wrapper的代码:
# function-1
def now(x,*args,**kw):
print('world peace')
# function-2
def wrapper(*args,**kw):
print("This is log")
return now(*args,**kw)
这样wrapper便实现了再now前面追加代码的目的,但这样并不符合装饰器的定义,now和wrapper再相似,毕竟也是两个函数
那如果直接执行 now = wrapper,不就行了吗?确实行了,但这仅实现了对一个单一固定函数的包装,要想实现一个通用的装饰器还得定义一个通用的函数。
2.two
既然是装饰器是通用函数,那么上述wrapper()代码块中的now只能是一个变量,改为以下代码:
func = now
# function-2
def wrapper(*args,**kw):
print("This is log")
return func(*args,**kw)
3.three
封装成一个函数,这里把wrapper函数当成一个参数传了出去,1.one说过如果直接执行now = wrapper,那么可以实现装饰器的目的(只是无法通用)。那么现在传出去的wrapper再次赋值给now函数本身,那么绕了一圈终于还是做到了now = wrapper
def log(func):
def wrapper(*args, **kw):
print('This is log')
return func(*args, **kw)
return wrapper
4.four
本文第一个代码块中展示的代码中,@log相当于执行了func = log(func)。这里也就是now = log(now),结合上面所讲,相当于now = wrapper.
@log
def now():
print('2015-3-25')