13、装饰器
其本质:在不需要做任何代码变动的前提下,增加额外的功能。装饰器返回的是一个函数对象。
相当于把函数作为参数传递进去,然后对函数进行装饰
其本质就是一个闭包
作用:
- 给原来的函数增加额外的功能
- 把原来的函数作为参数传递进去
13.1 基本用法
标准版的装饰器
def wrapper(func): #func为原来的函数名
def inner(*agrs,**kwargs):
# 执行被装饰函数之前的操作
ret = func(*agrs,**kwargs)
# 执行被装饰函数之后的操作
return ret
return inner
def test():
print("发表评论:很喜欢~")
#test()
def wrapper(func): #外函数 , func为原来的函数名
def inner(): #内函数
print("是否登录:已经登录")
ret = func() #调用func函数
print("是否退出")
return ret
return inner
new_test = wrapper(test)
new_test()
13.2 语法糖用法 @装饰器名称
用法
@装饰器名称
def wrapper(func):
def inner():
print("是否已经登录")
func()
return inner
@wrapper #wrapper为装饰器的名称,就是一个函数
#被装饰的函数
def test2():
print("转发微博")
@warpper
def test3():
print("发微博")
test()
# 结果
# 是否已经登录
# 转发微博
test3()
# 结果
# 是否已经登陆
# 发微博
def wrapper(func,fn):
def inner():
print("最开始")
func()
fn()
return inner
def test2():
print("转发微博")
def test3():
print("发微博")
new_test = wrapper(test1,test2)
new_test()
13.3 带参数的装饰器
使用语法糖的方式
def outer(fn):
def inner(a,b):
print(f'{a},{b}')
fn(a,b)
return inner
@outer
def test(a,b): #要有两个参数
print("hello")
test(1,2)
不使用语法糖的方式
def outer(fn):
def inner(a,b):
print(f'{a},{b}')
fn()
return inner
def test():
print("hello")
test = outer(test)
test(1,2)
13.4 带不定长参数的装饰器
def test(*args, **kwargs):
print(args)
print(kwargs)
def wrapper(func):
def inner(*args, **kwargs):
print("开始")
func(*args, **kwargs)
print("结束")
return inner
test = wrapper(test)
test()
13.5 多个装饰器
# 第一个装饰器
def maketest1(fn):
def inner():
return "你好啊" + fn() + '结束'
return inner
# 第二个装饰器
def maketest2(fn):
def inner():
return "第二个" + fn() + "第二个结束"
return inner
# 被装饰的第一个函数
@maketest1
def test1():
return "留下来补课"
print(test1())
# 被装饰的第二个
@maketest2
def test2():
return "我要改名了"
print(test2())
# 被装饰的第三个
@maketest1 #再用maketest1进行装饰
@maketest2 #先用maketest2进行装饰
def test3():
return "江湖没有传说"
print(test3())