Python Decorator装饰器的创建方法及常用场景分析

 更新时间:2022年07月04日 09:51:18   作者:什么都干的派森  
这篇文章主要介绍了Python Decorator装饰器的创建方法及常用场景,装饰器可以分成方法装饰器和类装饰器,他们的区别是一个是用函数实现的装饰器,一个是用类实现的装饰器,他们也都能在方法和类上进行装饰,需要的朋友可以参考下

前言

1.装饰器本质是一个语法糖,是对被装饰方法或类进行的功能扩充,是一种面向切面的实现方法
2.装饰器可以分成方法装饰器和类装饰器,他们的区别是一个是用函数实现的装饰器,一个是用类实现的装饰器,他们也都能在方法和类上进行装饰
3.类装饰器看起来结构更加清晰,因此下面的代码实现的装饰器全是类装饰器

一、创建方式

1.创建“装饰方法”的类装饰器

from functools import wraps
# 装饰器类
class MyDecorator(object):
    def __init__(self, plusNum):
        self.plusNum = plusNum  # 装饰器入参
    def __call__(self, func):
        @wraps(func)    # @wraps保证装饰器不改变被装饰方法的原有函数结构
        def wrapped_function(*args, **kwargs):
            # 调用被装饰方法前执行一些操作 ---------------
            # 如果不加@wraps,此处打印结果将是
            funcName = func.__name__
            print("funcName: {}".format(funcName))
            # ---------------------------------------
            # 修改被装饰方法的入参 --
            num1 = args[0] + 2
            num2 = args[1] + 3
            args = (num1, num2)
            # -------------------
            # 执行被装饰方法 -------------
            res = func(*args, **kwargs)
            # -------------------------
            # 调用被装饰方法后执行一些操作 -------------
            print("do something after the func...")
            # -------------------------------------
            # 修改被装饰方法的出参 --
            res += self.plusNum
            # -------------------
            # 返回被装饰方法的参数
            return res
        # 返回装饰器方法
        return wrapped_function
# 被装饰的方法
@MyDecorator(3)
def add(num1, num2):
    return num1+num2
if __name__ == '__main__':
    # 整体执行流程:
    # 1. 打印 add 方法名
    # 2. 修改被装饰方法入参
    # 3. 执行被装饰方法
    # 4. 调用被装饰方法后执行一些操作
    # 5. 修改被装饰方法的出参
    # 6. 打印结果
    print(add(5, 3))
    # funcName: add
    # do something after the func...
    # 16

2.创建“装饰类中方法”的类装饰器

from functools import wraps
# 装饰器类
class MyDecorator(object):
    def __init__(self, plusNum):
        self.plusNum = plusNum  # 装饰器入参
    def __call__(self, func):
        @wraps(func)    # @wraps保证装饰器不改变被装饰方法的原有函数结构
        def wrapped_function(*args, **kwargs):
            # 此处与直接装饰方法相同
            # 调用被装饰方法前执行一些操作 ---------------
            # 如果不加@wraps,此处打印结果将是
            funcName = func.__name__
            print("funcName: {}".format(funcName))
            # ---------------------------------------
            # 此处需要注意,如果需要修改入参的值,那么传参的索引是从1开始而不是从0开始,因为第一个入参的值是实例本身self
            # 修改被装饰方法的入参 --
            num1 = args[1] + 2
            num2 = args[2] + 3
            args = (args[0], num1, num2)
            # -------------------
            # 此处与直接装饰方法相同
            # 执行被装饰方法 -------------
            res = func(*args, **kwargs)
            # -------------------------
            # 此处与直接装饰方法相同
            # 调用被装饰方法后执行一些操作 -------------
            print("do something after the func...")
            # -------------------------------------
            # 此处与直接装饰方法相同
            # 修改被装饰方法的出参 --
            res += self.plusNum
            # -------------------
            # 返回被装饰方法的参数
            return res
        # 返回装饰器方法
        return wrapped_function
class Operation(object):
    # 被装饰的类方法
    @MyDecorator(3)
    def add(self, num1, num2):
        return num1+num2
if __name__ == '__main__':
    op = Operation()
    print(op.add(3, 5))
    # funcName: add
    # do something after the func...
    # 16

3.创建“装饰类”的类装饰器

from functools import wraps
# 装饰器类
class MyDecorator(object):
    def __init__(self, plusNum):
        self.plusNum = plusNum  # 装饰器入参
    def __call__(self, Cls):
        @wraps(Cls)    # @wraps保证装饰器不改变被装饰类的原有结构
        def wrapped_function(*args, **kwargs):
            # 调用被装饰类前执行一些操作 ---------------
            # 如果不加@wraps,此处打印结果将是
            clsName = Cls.__name__
            print("clsName: {}".format(clsName))
            # ---------------------------------------
            # 修改被装饰类的入参 ---
            num1 = args[0] + 2
            num2 = args[1] + 3
            args = (num1, num2)
            # -------------------
            # 初始化被装饰类 -------------
            cls = Cls(*args, **kwargs)
            # -------------------------
            # 初始化后执行一些操作 --------------------
            print("do something after the func...")
            # -------------------------------------
            # 给类实例增加增加属性和方法 ---------------------
            cls.mul = 3                         # 增加属性
            cls.plusNumber = self.plusNumber    # 增加方法
            # -------------------------------------------
            # 返回实例
            return cls
        # 返回装饰器方法
        return wrapped_function
    def plusNumber(self, num):
        return num + self.plusNum
# 被装饰的类
@MyDecorator(3)
class Operation(object):
    def __init__(self, num1, num2):
        self.num1 = num1
        self.num2 = num2
    def add(self):
        num3 = self.num1 + self.num2
        num4 = self.plusNumber(num3*self.mul)    # 使用装饰器插入的属性和方法
        return num4
if __name__ == '__main__':
    # 整体执行流程:
    # 1. 打印 Operation 类名
    # 2. 修改类的初始化参数
    # 3. 初始化类
    # 4. 初始化完成后执行一些方法
    # 5. 给初始化的实例新增 mul 属性和 plusNumber 方法
    # 6. 实例执行 add 函数并调用新增的装饰函数和装饰属性
    # 7. 输出结果
    op = Operation(3, 5)
    print(op.add())
    # clsName: Operation
    # do something after the func...
    # 42

二、常用场景

1.记录日志

# todo

2.性能测试

# todo

3.循环执行

# todo

4.拦截器

# todo

5.数据预处理(数据清洗)

# todo

6.功能植入

# todo

到此这篇关于Python Decorator装饰器的创建方法及常用场景的文章就介绍到这了,更多相关Python Decorator装饰器内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Python eval()和exec()函数使用详解

    Python eval()和exec()函数使用详解

    exec函数执行的是python语句,没有返回值,eval函数执行的是python表达式,有返回值,exec函数和eval函数都可以传入命名空间作为参数,本文给大家介绍下Python eval()和exec()函数,感兴趣的朋友跟随小编一起看看吧
    2022-11-11
  • python制作的天气预报小工具(gui界面)

    python制作的天气预报小工具(gui界面)

    大家好啊!我用Tkinter写了一个天气预报小工具,支持34个省级行政区以及港澳台地区天气,覆盖全面。程序打包好放在了蓝奏云,与大家分享一下。
    2021-05-05
  • Python中shape[0]、shape[1]和shape[-1]分别的意思详解(附代码)

    Python中shape[0]、shape[1]和shape[-1]分别的意思详解(附代码)

    刚开始使用python做东西,总是不太理解矩阵、数组相关的问题,所以在此记录shape方面的总结,下面这篇文章主要给大家介绍了关于Python中shape[0]、shape[1]和shape[-1]分别是什么意思的相关资料,需要的朋友可以参考下
    2022-11-11
  • PyQt6中自定义浮点型滑块类的实现

    PyQt6中自定义浮点型滑块类的实现

    在PyQt6中,滑块是常用的用户界面元素之一,用于选择数值范围,本文主要介绍了PyQt6中自定义浮点型滑块类的实现,具有一定的参考价值,感兴趣的可以了解一下
    2024-03-03
  • Python实现aes加密解密多种方法解析

    Python实现aes加密解密多种方法解析

    这篇文章主要介绍了Python实现aes加密解密多种方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-05-05
  • python 装饰器的使用与要点

    python 装饰器的使用与要点

    python的装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能;装饰器的返回值也是一个函数对象。简单的说装饰器就是一个用来返回函数的函数
    2021-05-05
  • 解决win10 vscode 无法激活python 虚拟环境的问题

    解决win10 vscode 无法激活python 虚拟环境的问题

    这篇文章主要介绍了win10 vscode 无法激活python 虚拟环境的解决办法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-10-10
  • python爬虫系列网络请求案例详解

    python爬虫系列网络请求案例详解

    这篇文章主要介绍了【Python从零到壹】python爬虫系列-网络请求,从零开始学习Python网络爬虫,如何从中获取需要的数据信息,现整理出零基础如何学爬虫技术以供学习
    2021-04-04
  • 利用Python封装MySQLHelper类实现数据库的增删改查功能

    利用Python封装MySQLHelper类实现数据库的增删改查功能

    Python 连接 MySQL 的方法有很多,常用的有 pymysql 和 mysql-connector-python 两种库,本文主要介绍了如何封装一个MySQLHelper类,实现对数据库的增删改查功能,感兴趣的可以了解一下
    2023-06-06
  • python如何操作mysql

    python如何操作mysql

    这篇文章主要介绍了python如何操作MySQL,帮助大家更好的理解和学习python,感兴趣的朋友可以了解下
    2020-08-08

最新评论