# 将函数当作参数传入装饰器
# 入门用法:日志打印器
def logger(func):
def wrapper(*args,**kw):
# *args的用法:当传入的参数个数未知,且不需要知道参数名称时
# 会将调用时的key=value参数全部打包到kw这个dict对象内
print('准备开始执行:{}函数了'.format(func.__name__))
# 真正执行的是这行
func(*args,**kw)
print('计算完毕!')
return wrapper
@logger
def add(x,y):
print('{}+{}={}'.format(x,y,x+y))
add(200,20)
# 入门用法:时间计时器
def timer(func):
def wrapper(*args,**kw):
t1=time.time()
# 函数真正执行的地方
func(*args,**kw)
t2=time.time()
cost_time=t2-t1
print('花费时间:{}秒'.format(cost_time))
return wrapper
import time
@timer
def want_sleep(sleep_time):
time.sleep(sleep_time)
want_sleep(10)
# 进阶:带参数的装饰器 根据国籍打招呼
def say_hello(contry):
def wrapper(func):
def deco(*args, **kwargs):
if contry == "china":
print("你好!")
elif contry == "america":
print('hello.')
else:
return
# 真正执行函数的地方
func(*args, **kwargs)
return deco
return wrapper
@say_hello("china")
def chinese():
print('来自中国')
@say_hello("america")
def america():
print('from america')
chinese()
america()
# 不带参数的类装饰器
# __init__:接收被装饰函数
# __call__:实现装饰逻辑
class logger(object):
def __init__(self,func):
self.func=func
def __call__(self, *args, **kwargs):
print('[INFO]:the function {}() is running...'.format(self.func.__name__))
return self.func(*args, **kwargs)
@logger
def say(sth):
print('say {}!'.format(sth))
say('hello')
# 高阶:带参数的类装饰器
# __init__:不再接收被装饰函数,而是接收传入参数
# __call__:接收被装饰函数,实现装饰逻辑
class logger(object):
def __init__(self,level='INFO'):
self.level=level
def __call__(self,func):
def wrapper(*args,**kwargs):
print('[{}]:the function {}() is running...'.format(self.level,func.__name__))
func(*args,**kwargs)
return wrapper # 返回函数
@logger(level='WARNING')
def say(sth):
print('say {}!'.format(sth))
say('hello')
# 使用偏函数与类实现装饰器
# 偏函数:functools.partial的作用就是,把一个函数的某些参数给固定住(也就是设置默认值),返回一个新的函数,调用这个新函数会更简单。
import time
import functools
class DelayFunc:
def __init__(self,duration,func):
self.duration = duration
self.func = func
def __call__(self, *args, **kwargs):
print(f'Wait for {self.duration} seconds...')
time.sleep(self.duration)
return self.func(*args,**kwargs)
def eager_call(self,*args,**kwargs):
print('Call without delay')
return self.func(*args,**kwargs)
def delay(duration):
'''
装饰器:推迟某个函数的执行
同时提供.eager_call方法立即执行
'''
# 为了避免定义额外函数
# 直接使用functools.partitial帮助构造DelayFunc 实例
return functools.partial(DelayFunc,duration)
@delay(duration=2)
def add(a,b):
return a+b
add(3,5)
# wraps装饰器有什么用?偏函数对象
# 方法一
from functools import wraps
def wrapper(func):
@wraps(func)
def inner_function():
pass
return inner_function
@wrapper
def wrapped():
pass
print(wrapped.__name__)
# 方法二
from functools import update_wrapper
WRAPPER_ASSIGNMENTS = ('__module__', '__name__', '__qualname__', '__doc__',
'__annotations__')
def wrapper(func):
def inner_function():
pass
update_wrapper(inner_function, func, assigned=WRAPPER_ASSIGNMENTS)
return inner_function
@wrapper
def wrapped():
pass
print(wrapped.__name__)
# 内置装饰器:property
# 存在于类中,可以将一个函数定义成一个属性,属性的值就是函数return的内容
# 同时会将这个函数变成另外一个装饰器,比如使用的@age.setter和@age.deleter
class Student(object):
def __init__(self, name):
self.name = name
self.name = None
@property
def age(self):
return self._age
@age.setter
def age(self, value):
if not isinstance(value, int):
raise ValueError('输入不合法:年龄必须为数值!')
if not 0 < value < 100:
raise ValueError('输入不合法:年龄范围必须0-100')
self._age = value
@age.deleter
def age(self):
del self._age
XiaoMing = Student("小明")
# 设置属性
XiaoMing.age = 25
# 查询属性
print(XiaoMing.age)
# 删除属性
del XiaoMing.age
# 原文章链接:https://www.jb51.net/article/168276.htm
python 类的装饰器
最新推荐文章于 2024-08-30 11:16:31 发布