Python装饰器详情

编辑: admin 分类: python 发布时间: 2021-11-14 来源:互联网
目录
  • 1、装饰器
    • 1.1 应用场景
  • 2、万能装饰器
    • 3、多层装饰器
      • 4、带参数的装饰器

        1、装饰器

        装饰器(Decorator):从字面上理解,就是装饰对象的器件。可以在不修改原有代码的情况下,为被装饰的对象增加新的功能或者附加限制条件或者帮助输出。

        装饰器的特点是特点是函数是作为其参数出现的,装饰器还拥有闭包的特点。

        示例代码如下所示:

        # 定义一个装饰器
        def decorate(func):
            def wrapper():
                func()
                print("已将学生加入学校学生名单")
                print("已将学生加入系学生名单")
                print("已将学生加入班级名单")
        
            return wrapper
        
        
        @decorate
        def student():
            print("我是小花")
        
        
        student()
        '''
        ---输出结果---
        我是小花
        已将学生加入学校学生名单
        已将学生加入系学生名单
        已将学生加入班级名单
        '''
        
        

        使用**@****符号加函数名**来装饰一个函数

        执行流程:因为student是被装饰的函数,系统将student函数以参数的形式传入decorate函数(装饰器decorate),执行decorate函数,并将返回值赋给student函数。

        上一段代码等于下面这一段代码:

        # 定义一个装饰器
        def decorate(func):
            def wrapper():
                func()
                print("已将学生加入学校学生名单")
                print("已将学生加入系学生名单")
                print("已将学生加入班级名单")
        
            return wrapper
        
        
        def student():
            print("我是小花")
        
        
        # 将返回值传给f 并调用
        f = decorate(student)  # 这里不能加(),不然就表示调用
        f()
        '''
        ---输出结果---
        我是小花
        已将学生加入学校学生名单
        已将学生加入系学生名单
        已将学生加入班级名单
        '''
        
        

        如果student函数外有直接可执行的语句,在不调用student函数的情况下,也会被执行,

        示例代码如下:

        # 定义一个装饰器
        def decorate(func):
            print("这是外部的代码")
        
            def wrapper():
                func()
                print("已将学生加入学校学生名单")
                print("已将学生加入系学生名单")
                print("已将学生加入班级名单")
        
            return wrapper
        
        
        @decorate
        def student():
            print("我是小花")
        
        
        # student()
        '''
        ---输出结果---
        这是外部的代码
        '''
        
        

        1.1 应用场景

        可以用于电商网站的判断用户是否登录来是否继续往下执行;添加日志等场景,

        示例代码如下所示:

        # 定义一个装饰器
        def decorate(func):
            def wrapper():
                func()
                print("正在检验用户是否登录")
                # if  # 判断是否登录的代码块
                #     pass
                print("用户已登录")
        
            return wrapper
        
        
        @decorate  # 使用装饰器
        def add_shopping_cart():
            print("添加成功")
        
        
        @decorate  # 使用装饰器
        def payment():
            print("付款成功")
        
        
        add_shopping_cart()
        payment()
        
        '''
        ---输出结果---
        添加成功
        正在检验用户是否登录
        用户已登录
        付款成功
        正在检验用户是否登录
        用户已登录
        '''
        
        

        2、万能装饰器

        因为函数的参数可能是不固定的,所以可以通过函数的可变参数来完成这种功能。

        示例代码如下:

        def decorate(func):
            def wrapper(*args, **kwargs):  # 使用可变参数来达到可以接受任何参数的效果
                print("正在检测中。。。")
                print(".............")
                print("检测完毕")
                func(*args, **kwargs)
        
            return wrapper
        
        
        @decorate  # 使用装饰器
        def f1():  # 无参数
            print("这个没有任何功能")
        
        
        @decorate
        def f2(name):  # 一个参数
            print("名字是:", name)
        
        
        @decorate
        def student(*students):  # 多个参数  # *students用于接收多个参数
            for ch in students:
                print(ch)
        
        
        @decorate
        def student_classroom(*students, classroom="前端班"):  # 接收可以赋值的参数
            print(f"这是{classroom}的学生")
            for ch in students:
                print(ch)
        
        
        # 调用函数
        f1()
        '''
        ---输出结果---
        正在检测中。。。
        .............
        检测完毕
        这个没有任何功能
        '''
        f2("一碗周")
        '''
        ---输出结果---
        正在检测中。。。
        .............
        检测完毕
        名字是: 一碗周
        '''
        student("张三", "李四", "王五")
        '''
        ---输出结果---
        正在检测中。。。
        .............
        检测完毕
        张三
        李四
        王五
        '''
        student_classroom("张三", "李四", "王五", classroom="前端班")
        '''
        正在检测中。。。
        .............
        检测完毕
        这是前端班的学生
        张三
        李四
        王五
        '''
        
        

        为了防止错误,在定义装饰器的时候要将其设置为万能装饰器

        3、多层装饰器

        多层的执行循序执行顺序是从里到外,最先调用最里层的装饰器,最后调用最外层的装饰器,

        示例代码如下所示:

        def maths(func):  # 定义第一个装饰器
            def wrapper(*args, **kwargs):
                func(*args, **kwargs)
                print("该学生已经学习了数学")
        
            return wrapper
        
        
        def Chinese(func):  # 定义第而个装饰器
            def wrapper(*args, **kwargs):
                func(*args, **kwargs)
                print("该学生已经学习了语文")
        
            return wrapper
        
        
        def English(func):  # 定义第三个装饰器
            def wrapper(*args, **kwargs):
                func(*args, **kwargs)
                print("该学生已经学习了英语")
        
            return wrapper
        
        
        @maths
        @English
        def student1(name):
            print(f"学生{name}已经完成了")
        
        
        @韩国cn2服务器http://www.558idc.com/kt.htmlEnglish
        @Chinese
        @maths
        def student2(name):
            print(f"学生{name}已经完成了")
        
        
        # 调用函数
        student1("小明")
        '''
        学生小明已经完成了
        该学生已经学习了英语
        该学生已经学习了数学
        '''
        student2("小花")
        '''
        学生小花已经完成了
        该学生已经学习了数学
        该学生已经学习了语文
        该学生已经学习了英语
        '''
        
        

        4、带参数的装饰器

        带参数的装饰器一共分为三层,分别如下:

        • 第一层:负责接收装饰器的参数
        • 第二层 :负责接收函数
        • 第三层:负责接收函数的参数

        示例代码如下所示:

        # 装饰器带参数
        def outer(a):  # 第一层: 负责接收装饰器的参数
        
            def decorate(func):  # 第二层 : 负责接收函数
        
                def wrapper(*args, **kwargs):  # 第三层   负责接收函数的参数
                    for i in range(a):
                        print(i)
                    func(*args, **kwargs)
        
                return wrapper  # 返出来的是:第三层
        
            return decorate  # 返出来的是:第二层
        
        
        @outer(3)
        def number():
            print("打印完毕")
        
        
        number()
        '''
        0
        1
        2
        打印完毕
        '''
        
        

        最外层的函数负责接收装饰器参数,里面的内容还是原装饰器的内容。

        到此这篇关于Python装饰器详情的文章就介绍到这了,更多相关Python装饰器内容请搜索hwidc以前的文章或继续浏览下面的相关文章希望大家以后多多支持hwidc!