目录
Python装饰器
Python装饰器的理解
装饰器就是包装器,是包装和装修的意思。比如,有一个普通函数,现在需要在不改变这个函数代码的情况下,给它添加新功能。
函数嵌套可以实现装饰器功能,就是把普通函数放到另一个函数内部,在外层函数中添加新功能,达到包装的效果。
Python中一切皆对象,int和list是对象,函数也是对象,对象名称就是函数名,可以作为其他函数的参数。内层函数名也可以作为外层函数的返回值。
# 普通功能函数
def myfun():
print("hello,myfun")
# 直接调用普通函数
myfun()
print("-----------------------------")
# 装饰器函数
def deco(afun):
def infun():
print("before do")
afun()
print("after do")
return infun # 将包装后的内层函数作为返回值,供外界调用
# 将普通函数名传入装饰器
test_deco=deco(myfun)
# 调用装饰器函数
test_deco()
运行结果
C:UsershccmaAnaconda3python.exe E:/wkp01/p00/test01/py001/t09.py
hello,myfun
-----------------------------
before do
hello,myfun
after do
Process finished with exit code 0
Python装饰器与@语法以及wraps工具
Python提供@语法,使装饰器通过注解来实现。这样在形式上感觉原函数(普通函数)在使用上似乎没有变化。这样有个好处就是,以前使用普通函数的地方不需要改动就能全部添加装饰器中的内容。
Python内置的functools.wraps
工具可以保证原函数(普通函数)的名字和注释文档经过装饰器后能正常显示(而不是显示装饰器自己的内容)。这样才能做到既包装,又不留痕迹。
from functools import wraps
# 装饰器函数
def deco(afun):
@wraps(afun)
def infun():
print("before do")
afun()
print("after do")
return infun # 将包装后的内层函数作为返回值,供外界调用
@deco
def myfun():
print("hello,myfun")
# 普通函数变成了装饰器函数了,再也不普通
myfun()
运行结果
C:UsershccmaAnaconda3python.exe E:/wkp01/p00/test01/py001/t09.py
before do
hello,myfun
after do
Process finished with exit code 0
Python装饰器带参数
为了使装饰器能够包装各种函数(是否带参数,参数个数可多可少),我们需要在装饰器中使用函数可变参数特性。
from functools import wraps
# 装饰器函数
def deco(afun):
@wraps(afun)
def infun(*args,**kw):
print("before do")
for item in args:
print(item) # 可变参数
res=afun(*args,**kw)
print("after do")
return res
return infun # 将包装后的内层函数作为返回值,供外界调用
@deco
def myfun(x,y):
print("hello,myfun:",x+y)
# 普通函数变成了装饰器函数了,再也不普通
myfun(1,2)
运行结果
C:UsershccmaAnaconda3python.exe E:/wkp01/p00/test01/py001/t09.py
before do
1
2
hello,myfun: 3
after do
Process finished with exit code 0
Python装饰器可以用类实现
在Python装饰器既可以用函数实现,也可以用对象(类)实现,这里不作展开讲解。
装饰器模式是一种设计模式,一种编程思想。