1、装饰器的由来
想扩展自己的函数功能,又不想动自己原先的函数代码逻辑,那就得用装饰器,在其他语言里例如java 叫做面向切面编程,老师会给我们讲一堆面向切面底层实现的原理的过程中,我相信你已经丧失了对Java学习的兴趣,伤害永远是对比出来的,哈哈~。
在这里我会全面简单的介绍一下,装饰器有几种模式,不强调你使用哪种模式,按你的需求来。
2、初级自定义装饰器
func为函数名称,这里的思想是把函数作为参数传递给固定某一个函数,这种属于把函数转换为参数的思想。目的有很多种,比较实用的目的是让我们的各种功能行为更加符合规范.举例:比如我们之前有吃早饭,吃晚饭,吃中午饭函数,函数太多记不住,我们就定义了一个吃饭的函数,把吃晚饭、吃中午饭、吃早饭降维为参数进行传递和调用。
def say_Chinese():
return "我是say_Chinese"
def say_English():
return "我是say_English"
def say(func):
return func()
say(say_Chinese)
3、中级自定义装饰器
初级装饰器其实已经满足了我们的需求,为什么要学中级装饰器呢,我们通过wrapFunction 来更改你传进来func 函数的前后的逻辑行为,say_middle 你可以定义多个wrapFunction1,2 来满足各种行为逻辑,并且根据判断条件return 返回对应的装饰器函数即可。
def say_middle(func):
# 装饰函数
def wrapFunction():
print("说话之前,准备演讲稿") #
say_style = func()
print("说话完毕,进行总结")
return say_style
return wrapFunction
@say_middle
def say_People():
return "我是say_People"
# 因为say_People 头顶上装饰了say_middle
# 在调用say_People时候对say_People自动进行装饰。
# @say_middle 是最常用的。
say_People()
当我们想要知道当前执行的是哪个被装饰过得名称的时候。
print(say_People.__name__) # 打印的却是wrapFunction
# 为了解决优化这个问题,下面改进下我们的装饰器
4、改进装饰器
# 为不改变被装饰函数或类的性质,添加functools.wrap装饰器
from functools import wraps
def say_high(func):
@wraps(func)
def wrapFunction():
print("说话之前,准备演讲稿")
say_style = func()
print("说话完毕,进行总结")
return say_style
return wrapFunction
5、在类中创建装饰器
有的时候我们的装饰器更加独立化,类和模块都可以用来创建装饰器,Python对于创建装饰器没有限制,这完全取决于你。
为啥类能当装饰器,是因为Python提供了一个特殊的方法call 意味着类的实例可以当做函数来调用。
class Say_Super:
def __call__(self, func):
@wraps(func)
def wrapFunction():
print("说话之前,准备演讲稿") #
say_style = func()
print("说话完毕,进行总结")
return say_style
return wrapFunction
@Say_Super()
def say_Code():
return "我是say_Code"
say_Code()
6、带参数的装饰器
我们之前定义了都是不带参数的函数,其实不带参数的函数,say_Chinese、say_People的,都是没有灵魂的,因为这些函数,只能处理写成固定逻辑的功能,带参数就会让我们的功能更强,更灵活,因为有了值得判断和比较就会执行不同逻辑的代码。*args, **kwargs 一个是关键字参数,一个是命名关键字参数,目的是让函数可以灵活的传递各类型的参数。如果这块薄弱了,赶紧看看同乐老师录制的Python自动化办公的第十五章基础增强篇,进行基础增强,当基础增强了,才能更能快速掌握Python 的进阶编程所需要的内容。
定义一个装饰器把返回的字符串改成大写。
def to_uppercase(func):
@wraps(func)
def wrapper(*args, **kwargs):
text = func(*args, **kwargs)
if not isinstance(text, str):
raise TypeError('你传的参数不是字符串,请重新输入')
return text.upper()
return wrapper
@to_uppercase
def say_Language(say_str):
return say_str
language = say_Language('speak chinese')
print(language) # 输出SPEAK CHINESE
7、在类的方法上使用装饰器
# 可以自定义重复请求的次数,和间隔的秒速
def retry_requests(retries=3, delay=5):
def try_request(fun):
@wraps(fun)
def retry_decorators(*args, **kwargs):
for _ in range(retries):
res = fun(*args, **kwargs)
print(res)
time.sleep(delay)
return retry_decorators
return try_request
class ApiRequest:
def __init__(self, url, headers):
self.url = url
self.headers = headers
@retry_requests(retries=5, delay=1)
def create_request(self):
res = requests.get(url=self.url, headers=self.headers)
return res
aq = ApiRequest('https://www.ztloo.com', headers=None)
aq.create_request()
8、解除装饰器函数
通过wrapped 关键字解除
@to_uppercase
def say_Language(say_str):
return say_str
new_say_Language = say_Language.__wrapped__
language = new_say_Language('speak chinese')
print(language) # 输出SPEAK CHINESE
当我们知道装饰器是咋回事的时候,其他的就需要积累,可以看看开源的模块中,的装饰器是如何管理,和实现的,让我们后续用最少的代码,实现功能最丰富的功能。
我是同乐,我为Python 自动化带盐!!!!!!!!!!!!!!!!!!