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装饰器内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Python语法详解之decorator装饰器

    python 是一门优雅的语言,有些使用方法就像魔法一样.装饰器(decorator)就是一种化腐朽性为神奇的技巧.最近一直都在使用 Tornado 框架,一直还是念念不忘 Flask .Flask 是我最喜欢的 Python 框架,最早被它吸引也是源自它使用装饰器这个语法糖(Syntactic sugar)来做 Router,让代码看上去就感觉甜甜的. Tornado 中的 Router 略显平淡,怀念 Flask 的味道,于是很好奇的想知道 Flask 是如何使用这个魔法.通过阅读 Flas

  • 深入了解和应用Python 装饰器 @decorator

    Python的装饰器(decorator)是一个很棒的机制,也是熟练运用Python的必杀技之一.装饰器,顾名思义,就是用来装饰的,它装饰的是一个函数,保持被装饰函数的原有功能,再装饰上(添油加醋)一些其它功能,并返回带有新增功能的函数对象,所以装饰器本质上是一个返回函数对象的函数(确切的说,装饰器应该是可调用对象,除了函数,类也可以作为装饰器). 在编程过程中,我们经常遇到这样的场景:登录校验,权限校验,日志记录等,这些功能代码在各个环节都可能需要,但又十分雷同,通过装饰器来抽象.剥离这部分代

  • python 装饰器(Decorators)原理说明及操作代码

    目录 1 必要的2个核心操作 1.1 核心操作1, 函数内部可以定义函数 1.2 核心操作2 函数可以作为对象被输入输出 1.2.1 核心操作2的前置条件,函数是对象 1.2.2函数作为输入 1.2.3 函数作为输出 2 尝试构造装饰器 3装饰器定义的简写 本文目的是由浅入深地介绍python装饰器原理 装饰器(Decorators)是 Python 的一个重要部分 其功能是,在不修改原函数(类)定义代码的情况下,增加新的功能 为了理解和实现装饰器,我们先引入2个核心操作: 1 必要的2个核心操

  • Python装饰器(decorator)定义与用法详解

    本文实例讲述了Python装饰器(decorator)定义与用法.分享给大家供大家参考,具体如下: 什么是装饰器(decorator) 简单来说,可以把装饰器理解为一个包装函数的函数,它一般将传入的函数或者是类做一定的处理,返回修改之后的对象.所以,我们能够在不修改原函数的基础上,在执行原函数前后执行别的代码.比较常用的场景有日志插入,事务处理等. 装饰器 最简单的函数,返回两个数的和 def calc_add(a, b): return a + b calc_add(1, 2) 但是现在又有新

  • Python装饰器decorator用法实例

    本文实例讲述了Python装饰器decorator用法.分享给大家供大家参考.具体分析如下: 1. 闭包(closure) 闭包是Python所支持的一种特性,它让在非global scope定义的函数可以引用其外围空间中的变量,这些外围空间中被引用的变量叫做这个函数的环境变量.环境变量和这个非全局函数一起构成了闭包. 复制代码 代码如下: def outer(x):     y = [1,2,3]     def inner():         print x         print y

  • 12步入门Python中的decorator装饰器使用方法

    装饰器(decorator)是一种高级Python语法.装饰器可以对一个函数.方法或者类进行加工.在Python中,我们有多种方法对函数和类进行加工,比如在Python闭包中,我们见到函数对象作为某一个函数的返回结果.相对于其它方式,装饰器语法简单,代码可读性高.因此,装饰器在Python项目中有广泛的应用. 装饰器最早在Python 2.5中出现,它最初被用于加工函数和方法这样的可调用对象(callable object,这样的对象定义有call方法).在Python 2.6以及之后的Pyth

  • python装饰器decorator介绍

    一.装饰器decorator decorator设计模式允许动态地对现有的对象或函数包装以至于修改现有的职责和行为,简单地讲用来动态地扩展现有的功能.其实也就是其他语言中的AOP的概念,将对象或函数的真正功能也其他辅助的功能的分离. 二.Python中的decorator python中的decorator通常为输入一个函数,经过装饰后返回另一个函数.  比较常用的功能一般使用decorator来实现,例如python自带的staticmethod和classmethod. 装饰器有两种形式:

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

    目录 前言 一.创建方式 二.常用场景 前言 1.装饰器本质是一个语法糖,是对被装饰方法或类进行的功能扩充,是一种面向切面的实现方法2.装饰器可以分成方法装饰器和类装饰器,他们的区别是一个是用函数实现的装饰器,一个是用类实现的装饰器,他们也都能在方法和类上进行装饰3.类装饰器看起来结构更加清晰,因此下面的代码实现的装饰器全是类装饰器 一.创建方式 1.创建“装饰方法”的类装饰器 from functools import wraps # 装饰器类 class MyDecorator(object

  • Python函数装饰器常见使用方法实例详解

    本文实例讲述了Python函数装饰器常见使用方法.分享给大家供大家参考,具体如下: 一.装饰器 首先,我们要了解到什么是开放封闭式原则? 软件一旦上线后,对修改源代码是封闭的,对功能的扩张是开放的,所以我们应该遵循开放封闭的原则. 也就是说:我们必须找到一种解决方案,能够在不修改一个功能源代码以及调用方式的前提下,为其加上新功能. 总结:原则如下: 1.不修改源代码 2.不修改调用方式 目的:在遵循1和2原则的基础上扩展新功能. 二.什么是装饰器? 器:指的是工具, 装饰:指的是为被装饰对象添加

  • python知识:装饰器@property到底有啥用途

    目录 一.提要 二.关于属性的约定 2.1 类绑定属性 2.2 对象绑定属性 2.3 私有属性 三.应用@property装饰器 3.1 将一个属性转成方法 3.2 私有化某些属性 3.3 关联性修改 3.4 删除属性的deleter方法 四.property()函数原理 总结 一.提要 python的@property是python的一种装饰器,是用来修饰方法的. python @property 装饰器使一个方法可以像属性一样被使用. 除此之外,还有几个使用场景,本文将叙述这些使用技巧. 二

  • Python函数装饰器实现方法详解

    本文实例讲述了Python函数装饰器实现方法.分享给大家供大家参考,具体如下: 编写函数装饰器 这里主要介绍编写函数装饰器的相关内容. 跟踪调用 如下代码定义并应用一个函数装饰器,来统计对装饰的函数的调用次数,并且针对每一次调用打印跟踪信息. class tracer: def __init__(self,func): self.calls = 0 self.func = func def __call__(self,*args): self.calls += 1 print('call %s

  • python使用装饰器和线程限制函数执行时间的方法

    本文实例讲述了python使用装饰器和线程限制函数执行时间的方法.分享给大家供大家参考.具体分析如下: 很多时候函数内部包含了一些不可预知的事情,比如调用其它软件,从网络抓取信息,可能某个函数会卡在某个地方不动态,这段代码可以用来限制函数的执行时间,只需要在函数的上方添加一个装饰器,timelimited(2)就可以限定函数必须在2秒内执行完成,如果执行完成则返回函数正常的返回值,如果执行超时则会抛出错误信息. # -*- coding: utf-8 -*- from threading imp

  • python使用装饰器作日志处理的方法

    装饰器这东西我看了一会儿才明白,在函数外面套了一层函数,感觉和java里的aop功能很像:写了2个装饰器日志的例子, 第一个是不带参数的装饰器用法示例,功能相当于给函数包了层异常处理,第二个是带参数的装饰器用法示例,将日志输出到文件. ``` #coding=utf8 import traceback import logging from logging.handlers import TimedRotatingFileHandler def logger(func): def inner(*

  • Python类装饰器实现方法详解

    本文实例讲述了Python类装饰器.分享给大家供大家参考,具体如下: 编写类装饰器 类装饰器类似于函数装饰器的概念,但它应用于类,它们可以用于管理类自身,或者用来拦截实例创建调用以管理实例. 单体类 由于类装饰器可以拦截实例创建调用,所以它们可以用来管理一个类的所有实例,或者扩展这些实例的接口. 下面的类装饰器实现了传统的单体编码模式,即最多只有一个类的一个实例存在. instances = {} # 全局变量,管理实例 def getInstance(aClass, *args): if aC

  • python @propert装饰器使用方法原理解析

    这篇文章主要介绍了python @propert装饰器使用方法原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 首先,@propert的作用是把类中的方法『变成』了属性,方便通过实例访问.propert可以有两种用法:可以把一个方法变成只读属性:可以对一些属性进行过滤. 想象这样一个场景,在实例化一个类之后,需要对类的一个属性进行赋值,这时候是没有对属性属性被赋予的值进行判断的,如果属性被赋予了一个不合适的值,那么代码在后面执行的时候就会

  • 如何实现一个python函数装饰器(Decorator)

    装饰器本质上是一个 Python 函数或类,它可以让其他函数或类在不需要做任何代码修改的前提下增加额外功能,装饰器的返回值也是一个函数/类对象.它经常用于为已有函数/类添加记录日志.计时统计.性能测试等. 首先定义一个倒计时函数,这个函数的功能非常简单,就是把n从当前值减少到0. def countdown(n): while n > 0: print('time' + str(n)) n -= 1 print(countdown.__name__) 程序输出: countdown 1.为函数增

随机推荐