• Python装饰器扫盲


    函数的嵌套

    def func(message):
        def getMessage(message):
            print("got a message {}".format(message))
        return getMessage(message)
    
    
    
    if __name__ == "__main__":
        func("我是海贼王")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    函数返回值是函数(闭包)

    def func2():
        def printMessage(message):
            print("got a message {}".format(message))
        return printMessage
    
    if __name__ == "__main__":
        func("我是海贼王")
    
        send_message = func2()
        send_message("我也是海贼王")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    简单的装饰器

    def my_decorator(func):
        def wrapper():
            print("wrapper of decorator")
            func()
        return wrapper
    
    
    def my_greet():
        print("hello 我是海贼王路飞")
    
    if __name__ == "__main__":
        func("我是海贼王")
    
        send_message = func2()
        send_message("我也是海贼王")
    
        decorate = my_decorator(my_greet)
    
        decorate()
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    my_greet 函数 被 my_decorator 函数 增强了,本来my_greet 函数只会输出 “hello 我是海贼王路飞”,经过my_decorator 的增强后,多了一句 wrapper of decorator

    利用Python的特性简化上面的调用流程

    def my_decorator(func):
        def wrapper():
            print("wrapper of decorator")
            func()
        return wrapper
    
    
    @my_decorator
    def my_greet():
        print("hello 我是海贼王路飞")
        
    my_greet()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    这里的@,我们称之为语法糖,@my_decorator就相当于前面的greet=my_decorator(greet)语句,只不过更加简洁

    带参数的装饰器

     # 带参数的装饰器
    def withArgsDecorator(func):
        def wrapper(message):
            print("with args of decorator")
            func(message)
        return wrapper
    
    @withArgsDecorator
    def greetWithName(name):
        print("我是 {}".format(name))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    多个参数的装饰器

    事实上,通常情况下,我们会把*args和kwargs,作为装饰器内部函数 wrapper() 的参数。*args和kwargs,表示接受任意数量和类型的参数,因此装饰器就可以写成下面的形式:

     # 带多个不定参数的装饰器
    def withArgsDecorator(func):
        def wrapper(*args,**kwargs):
            print("with args of decorator")
            func(*args,**kwargs)
        return wrapper
    
    @withArgsDecorator
    def greetWithName(name):
        print("我是 {}".format(name))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    类装饰器

    前面我们主要讲了函数作为装饰器的用法,实际上,类也可以作为装饰器。类装饰器主要依赖于函数__call_(),每当你调用一个类的示例时,函数__call__()就会被执行一次

    ## 定义一个类装饰器
    def my_class_decorator(cls):
       # 在类被实例化之前执行一些操作
       cls.some_attribute = "Added by the decorator"
       return cls  # 返回修改后的类
    
    ## 使用类装饰器来装饰一个类
    @my_class_decorator
    class MyClass:
       def __init__(self, value):
           self.value = value
    
    ## 创建类的实例
    obj = MyClass(42)
    
    ## 访问被类装饰器修改后的属性
    print(obj.some_attribute)  ## 输出 "Added by the decorator"
    在上面的示例中,my_class_decorator 是一个类装饰器,它接受一个类作为参数,并可以修改该类,然后返回修改后的类。当你用 @my_class_decorator 装饰 MyClass 类时,MyClass 类被传递给 my_class_decorator,它在其中添加了一个新的属性 some_attribute。然后,你可以在类的实例中访问这个属性。
    
    类装饰器可以用于各种用途,包括添加属性、方法、修改类的行为等。你可以根据需要编写自定义的类装饰器,以满足你的项目需求。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    装饰器用法实例

    装饰器在用户登录验证中的一个常见用法是,它可以用来检查用户是否已登录,以确保只有已登录的用户才能访问某些受保护的页面或执行某些操作。以下是一个示例,演示如何使用装饰器实现用户登录验证:

    pythonCopy code# 模拟用户登录状态
    is_user_logged_in = False
    
    # 定义用户登录验证装饰器
    def login_required(func):
        def wrapper(*args, **kwargs):
            if is_user_logged_in:
                return func(*args, **kwargs)
            else:
                return "请先登录"
        return wrapper
    
    # 使用装饰器来保护需要登录的功能
    @login_required
    def protected_function():
        return "这是一个受保护的功能,只有已登录用户才能访问"
    
    # 模拟用户登录
    is_user_logged_in = True
    
    # 调用受保护的功能
    result = protected_function()
    print(result)  # 输出 "这是一个受保护的功能,只有已登录用户才能访问"
    
    # 模拟用户未登录
    is_user_logged_in = False
    
    # 再次调用受保护的功能
    result = protected_function()
    print(result)  # 输出 "请先登录"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    在上述示例中,login_required 是一个装饰器,它检查用户是否已登录。如果用户已登录,则执行原始的函数(这里是protected_function),否则返回一个提示信息。通过在需要登录验证的功能上使用@login_required 装饰器,你可以确保只有已登录用户才能访问这些功能。

    在实际应用中,用户登录状态通常会与会话管理或身份验证系统相关联,而不是简单地使用一个布尔标志来表示。但是,这个示例演示了如何使用装饰器来实现用户登录验证的基本概念。你可以根据实际需求扩展这个概念,并与实际的用户身份验证机制集成。

  • 相关阅读:
    聚观早报 |三星将在印度生产5G设备;马斯克邀请盖茨开特斯拉Semi
    【双向数据绑定原理 vue2.0 与 vue3.0】
    从TF-IDF 到BM25, BM25+,一文彻底理解文本相关度
    ESP32-CAM初始篇:Arduino环境搭建-->实现局域网推流
    「实践篇」解决微前端 single-spa 项目中 Vue 和 React 路由跳转问题
    域名暂停解析是怎么回事?如何恢复解析?
    ARM体系结构与编程(更)
    NLP教程(3) - 神经网络与反向传播
    Spring MVC的执行流程
    【vue3】Transition过渡组件
  • 原文地址:https://blog.csdn.net/woshihaizeiwang/article/details/134022526