文章目录
1、什么是装饰器
装饰器可为函数增加新的功能,并且不改变原函数的:
- 内部结构
- 返回值
- 调用方式
2、函数可赋值给变量
例一:
def hello():
print("你好")
hi=hello
hi()
输出:
你好
例二:
def hello():
print("你好")
hi=hello
del hello #删除hello
hello()
NameError: name ‘hi’ is not defined
例三:
def hello():
print("你好")
hi=hello
del hello #删除hello
hi()
输出:
你好
3、函数嵌套
例一:
def say():
def hi():
print("你好")
def bye():
print("再见")
hi()
bye()
say()
输出:
你好
再见
例二:
def say():
def hi():
print("你好")
hi() #出了hi()的作用域
NameError: name ‘hi’ is not defined
4、从函数中返回函数
例一:
def say():
def hi():
print("你好")
return hi
a=say() #a将指向,say函数中的hi函数
print(a)
print(a())
输出:
<function say..hi at 0x000000DF56C729D8>
你好
None
5、函数做为参数传递给另一个函数
例一:
def hi():
return "你好"
def say(func):
print("说")
print(func())
say(hi)
输出:
说
你好
6、第一个装饰器
例一:
def say(func):
def wrapper():
print("调用fcunc前")
func()
print("调用fcunc后")
return wrapper
def hi():
print("你好")
hi()
输出:
你好
例二:
这差不多就算是一个装饰器了
def say(func):
def wrapper():
print("调用fcunc前")
func()
print("调用fcunc后")
return wrapper
def hi():
print("你好")
hi=say(hi) #调用装饰器
hi()
输出:
调用fcunc前
你好
调用fcunc后
例三:
用 @ 来运行例二的程序
def say(func):
def wrapper():
print("调用fcunc前")
func()
print("调用fcunc后")
return wrapper
@say
def hi():
print("你好")
hi()
输出:
调用fcunc前
你好
调用fcunc后
例四:
def say(func):
def wrapper():
print("调用fcunc前")
ret=func()
print("调用fcunc后")
return "返回wrapper"
return wrapper
@say
def hi():
print("你好")
return "返回hi"
ret=hi()
print(ret)
输出:
调用fcunc前
你好
调用fcunc后
返回wrapper
hi实际返回的是wrapper的返回值,下面我们让装饰器返回hi的返回值
例五:
def say(func):
def wrapper():
print("调用fcunc前")
ret=func()
print("调用fcunc后")
return ret
return wrapper
@say
def hi():
print("你好")
return "返回hi"
ret=hi()
print(ret)
输出:
调用fcunc前
你好
调用fcunc后
返回hi
这样就实现了,调用了hi后返回值也是hi的
7、适应原函数带参数的装饰器
7.1、原函数带一个参数
例一:
def say(func):
def wrapper(name):
print("调用fcunc前")
ret=func(name)
print("调用fcunc后")
return ret
return wrapper
@say
def hi(name):
print("你好%s"%name)
return "返回hi"
hi("锄禾")
输出:
调用fcunc前
你好锄禾
调用fcunc后
装饰器的缺点是,原函数形参数量变化以后,装饰器也需要对应维护
7.1、原函数不定长参数
下面这种形式的装饰器可以适应任意数量形参的原函数
例一:
def say(func):
def wrapper(*args,**kwargs):
print("调用fcunc前")
ret=func(*args,**kwargs)
print("调用fcunc后")
return ret
return wrapper
@say
def hi(name,age):
print("你好%s,我今年%s"%(name,age))
return "返回hi"
ret=hi("锄禾",18)
print(ret)
输出:
调用fcunc前
你好锄禾,我今年18
调用fcunc后
8、*args和**kwargs
详见
Python学海无涯路【第08回】:函数
2.4、不定长参数
9、为装饰器传参
例一:
def say_type(type=1):
def say(func):
def wrapper(*args,**kwargs):
if (1==type):
print("功能一")
else:
print("功能二")
ret=func(*args,**kwargs)
return ret
return wrapper
return say
@say_type(2) #为装饰器传参
def hi(name):
print("你好%s"%(name))
return "返回hi"
输出:
功能二
你好锄禾