Python装饰器
2022-01-18 11:47 何小六soso 阅读(28) 评论(0) 编辑 收藏 举报Python装饰器
在不变原有代码,且保持函数调用方不变的情况下,给原函数增加新的功能
原理:用一个函数/类,去装饰一个函数/类,生成一个新的函数/类
语法:在原有的函数上增加@符号,装饰器会把下面的函数当做参数传递装饰器中,@符为语法糖
场景:引入日志,函数执行时间的统计,执行函数前、后的工作,权限校验,缓存等场景
装饰器原型:闭包
利用闭包,把函数当做参数传递,并且在内函数调用传递进来的函数,并返回内函数
def outer(f): # 外函数
def inner(): # 内函数
f()
return inner() # 返回内函数
装饰器语法:
def outer(f): # 外函数
def inner(): # 内函数
print('我是外函数中的内函数11111')
f()
print('我是外函数中的内函数22222')
return inner # 返回内函数
# def old():
# print('我是一个老函数')
# outer(old)
'''
我是外函数中的内函数11111
我是一个老函数
我是外函数中的内函数22222
'''
#使用装饰器方法
@outer
def new():
print('我是一个新函数,使用装饰器调用')
new()
'''
我是外函数中的内函数11111
我是一个新函数,使用装饰器调用
我是外函数中的内函数22222
'''
装饰器的应用:统计函数执行时间
# 普通装饰器
def outer(f):
def inner():
print('准备学习。。。。1')
f()
print('学习完成。。。。2')
return inner
def two(f):
def inner():
print('第2层包裹。。。。3')
f()
print('第二层包裹。。。。4')
return inner
# 扩展装饰器
def kuozhan(f):
def inner():
print('扩展1。。。。5')
f()
print('扩展2。。。。6')
return inner
@kuozhan # 最外一层的包裹
@two
@outer #第一层包裹
def love():
print('学习python。。。。7')
love()
'''
执行顺序:5-3-1-7-2-4-6
outer-->two-->kouzhan,代码运行时逐层包裹
'''
多参数函数语法:
# 多参数装饰器
import time
def outer(f):
def inner(who, name, *args, **kwargs):
print('多参数迭代器开始执行')
f(who, name, *args, **kwargs)
print('多参数迭代器执行完毕')
return inner
# 定义多参数函数
@outer
def love(who, name, *args, **kwargs):
print(f'{who}教{name}学习python')
print(f'{who}教{name}学习', args)
print(f'{who}教{name}看书', kwargs)
love('王老师','王同学','java','PHP',book='C')
带参数装饰器语法:
# 带参数的装饰器,如果装饰器需要参数,那么当前装饰器需要套个壳,用于接收装饰器的参数
def kuozhan(var):
def outer(f):
def inner1():
print('做饭')
f()
print('吃饭')
def inner():
print(f'开始学习{var}')
f()
print('学习完成')
if var == 'python':
return inner
else:
return inner1
return outer
@kuozhan('java')
def love():
print('休息一下。。。。')
love()
类装饰器装饰函数语法:
# 类装饰器
class Outer():
def __call__(self, fun): # 魔术函数
self.fun = fun
return self.inner
def inner(self, name):
print('装饰器开始')
self.fun(name)
print('装饰器结束')
@Outer()
def love(name):
print(f'{name}学习python')
love('明明')
函数装饰器装饰类:
使用装饰器给类装饰,在类上方添加@装饰器对类进行装饰
装饰器给函数装饰,目的是不改变函数调用和代码的情况下给原函数增加了新的功能
装饰器给类装饰,目的是不改变类调用和代码的情况下给类增加新成员(属性和方法)
# 装饰器装饰类
# 使用函数装饰器,给类进行装饰,增加新的属性和方法
def kuozhan(cls): # 参数是类
def func():
print('装饰器中新增类方法')
cls.func = func
cls.name = '装饰器中新增类属性'
return cls # 返回修改后的类
@kuozhan
class Demo():
def love():
print('学习python')
Demo.love()
print(Demo.name)
Demo.func()