快乐学习
前程无忧、中华英才非你莫属!

Python进阶编程必备技能-装饰器

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 自动化带盐!!!!!!!!!!!!!!!!!!

打赏
赞(2) 打赏
未经允许不得转载:同乐学堂 » Python进阶编程必备技能-装饰器

特别的技术,给特别的你!

联系QQ:1071235258QQ群:710045715

觉得文章有用就打赏一下文章作者

非常感谢你的打赏,我们将继续给力更多优质内容,让我们一起创建更加美好的网络世界!

支付宝扫一扫打赏

微信扫一扫打赏

error: Sorry,暂时内容不可复制!