python装饰器

装饰器是:输入函数,并返回函数,的函数。是一个高阶/高层函数。是调用函数的函数。其返回值必须是一个函数。装饰器主要有以下三种类型:

    1. 单层的装饰器,只能在函数前面加东西。因为返回的是原始函数。
    1. 双层的装饰器,可以在函数前后加东西。返回的是内层函数。内层函数可以对被装饰函数进行修改。并在被装饰函数前后进行其他操作。 最内层函数可以不用返回函数,也可以不用返回任何数值。它仅仅使用了被装饰函数的结果,并且变成了新的被装饰函数。
    1. 三层的装饰器,可以给原函数添加新参数。逐次返回内层函数。 最外面函数负责传入新参数; 中间层函数负责装饰,其输入是被装饰的函数, 输出是最内层函数; 最内层函数负责装饰的具体内容,其输入是"*args, **kw",代表任意参数。最内层函数里面调用被装饰函数,并且使用了最外层函数传入的参数。 返回,修改后的被装饰函数的输出值。 在使用时,需要在装饰器后面加上参数。可以是多个参数。

注意: 当装饰器的函数结构超过(包含)两层时,需要在最内层函数前一行添加"@functools.wraps(func)",用于修改最内层函数的函数名为被装饰函数的函数名。

python 复制代码
import functools

def decorator_1(func):
    """
    单层的装饰器,只能在函数前面加东西,无法改变被装饰函数的输出结果。因为返回的是原始函数。
    """
    print(f"使用了单层装饰器:decorator_1")
    print(f"正在执行函数: {func.__name__}")  # 调用了函数
    return func

def decorator_2_case_1(func):
    """
    双层装饰器,可以在被装饰函数的前面和后面加东西。  该装饰器实际上装饰的是内层函数,返回的是内层函数。
    内层函数调用了被装饰的函数,需要在其前面添加命令"@functools.wraps(func)", 用于修改内层函数的函数名与被装饰函数的函数名一致。
    内层函数的参数是"*args, **kw",代表任意参数,用于普适化的传递被装饰函数的参数。
    
    """
    def inner(*args, **kw):
        print(f"使用了双层装饰器:decorator_2_case_1")
        print(f"正在执行函数: {func.__name__}")  # 调用了函数
        func(*args, **kw)
        print("执行函数结束。")
    return inner

def decorator_2_case_2(func):
    """
    双层的装饰器,除了可以在被装饰函数前后添加东西之外,(理论上)也可以修改被装饰函数的返回值,包括数据格式。
    但是,这种处理方式不推荐,除非用于校正已有函数的错误。否则有悖装饰器的初衷,不如重新写一个函数。
    再重复一遍:双层装饰器,本质上是装饰的内层函数,返回的也是内层函数,只不过内层函数调用了被装饰函数。
    """
    def inner(*args, **kw):
        print(f"使用了双层装饰器:decorator_2_case_2")
        print(f"正在执行函数: {func.__name__}")  # 调用了函数
        raw_result = func(*args, **kw)
        new_result = raw_result + 100
        print("执行函数结束。比原始数值增加了100.")
        return new_result
    return inner

def decorator_3(delta,aString):
    """
    三层装饰器,相比以上单层和双层装饰器,主要新增功能是:在装饰时传入新参数。
    最外层用于传入新参数;
    中间层用于传入被装饰函数;
    最内层用于同时使用新参数和被装饰函数,对被装饰函数的结果进行重新修改。
    总结:在最外层添加参数,在最里层使用。本质上装饰的是最内层函数,所以需要在最内层函数前面添加"@functools.wraps(func)"。
    """
    def decorator_middle(func):
        @functools.wraps(func)
        def decorator_inner(*args, **kw):
            print(f"使用了三层装饰器:decorator_3")
            print(f"正在执行函数: {func.__name__}。新增参数: {delta},{aString}")  # 调用了函数
            result = func(*args, **kw)
            new_result = result + delta
            print(f"执行函数结束。比原始数值增加了 {delta}.")
            return new_result
        return decorator_inner
    return decorator_middle

@ decorator_1
# @ decorator_2_case_1
# @ decorator_2_case_2
# @ decorator_3(88,"kkk")
def add(a,b):
    return a+b




if __name__ == "__main__":
    result = add(5,6)
    # print(result)
    # print("add.__name__ = ",add.__name__)

参考:

装饰器 - Python教程 - 廖雪峰的官方网站

相关推荐
kiramario20 分钟前
【结束】JS如何不通过input的onInputFileChange使用本地mp4文件并播放,nextjs下放入public文件的视频用video标签无法打开
开发语言·javascript·音视频
豌豆花下猫41 分钟前
Python 潮流周刊#90:uv 一周岁了,优缺点分析(摘要)
后端·python·ai
土豆儿@1 小时前
java之泛型
java·开发语言
橘猫云计算机设计1 小时前
基于SSM的《计算机网络》题库管理系统(源码+lw+部署文档+讲解),源码可白嫖!
java·数据库·spring boot·后端·python·计算机网络·毕设
小伍_Five1 小时前
从0开始:OpenCV入门教程【图像处理基础】
图像处理·python·opencv
m0_748245341 小时前
python——Django 框架
开发语言·python·django
曼巴UE51 小时前
UE5.3 C++ TArray系列(一)
开发语言·c++·ue5
熬夜苦读学习2 小时前
Linux文件系统
linux·运维·服务器·开发语言·后端
菜鸟一枚在这2 小时前
深度解析建造者模式:复杂对象构建的优雅之道
java·开发语言·算法
java1234_小锋2 小时前
一周学会Flask3 Python Web开发-客户端状态信息Cookie以及加密
前端·python·flask·flask3