详解Python装饰器的四种定义形式

目录
  • 前言
  • 用函数装饰函数
  • 用函数装饰一个类
  • 用类定义装饰器,然后装饰一个函数
  • 用类定义装饰器,然后装饰一个类
  • 小结

前言

装饰器(decorator)在Python框架中扮演着重要角色,是Python中实现切面编程(AOP)的重要手段。

aspect-oriented programming (AOP) ,在不改变代码自身的前提下增加程序功能

不改变代码自身,但需要在函数和类头上加一个标注(annotation),这个标注在Python里叫装饰器,在java里叫注解。
在Python里,一共有四种组合形式。下面一一举例。

用函数装饰函数

采用一个函数定义装饰器:

def decorate(f):
    def wrapper(*args):
        return f(*args)*2
    return wrapper

然后作用在一个函数上:

@decorate
def add(a, b):
	return a + b

测试一下效果:

def test_decorate():
	sum = add(3, 5)
	assert sum == 16

用函数装饰一个类

这里通过装饰器实现单例模式:

def singleton(cls):
    instances = {}
    def wrapper(*args, **kwargs):
        if cls not in instances:
          instances[cls] = cls(*args, **kwargs)
        return instances[cls]
    return wrapper

使用该装饰器:

@singleton
class MyClass:
    def method(self):
        pass

于是,当你定义多个对象时,返回的是同一实例:

obj = MyClass()  # creates a new instance
obj2 = MyClass()  # returns the same instance
obj3 = MyClass()  # returns the same instance
...

用类定义装饰器,然后装饰一个函数

先采用类定义一个装饰器:

class Star:
    def __init__(self, n):
        self.n = n

    def __call__(self, fn):
        @wraps(fn)
        def wrapper(*args, **kwargs):
            result = fn(*args, **kwargs)
            return result
        return wrapper

再作用在一个函数上:

@Star(5)
def add(a, b):
    return a + b

主要是在类中实现__call__方法。上面例子也可以简化:

class MyDecorator:
    def __init__(self, function):
        self.function = function

    def __call__(self, *args, **kwargs):

        # We can add some code
        # before function call

        self.function(*args, **kwargs)

        # We can also add some code
        # after function call.
# adding class decorator to the function
@MyDecorator
def function(name, message ='Hello'):
    print("{}, {}".format(message, name))

用类定义装饰器,然后装饰一个类

先定义装饰器:

class MyClassDecorator(object):
	_instances = dict()

	def __init__(self, name):
		pass

	def __call__(self, cls):
		class WrappedClass(cls):
			def say_hello(self):
				print(f'Hello: {self.username}')
		return WrappedClass

该装饰器给被装饰的类上添加了一个方法,名称为say_hello()。使用如下:

@MyClassDecorator('test')
class MyClass():
	def __init__(self, username):
		self.username = username

然后:

def test_decoratorforclass():
	obj = MyClass('user1')
	obj.say_hello()

打印出: Hello: user1

小结

学习类装饰,对Python的内部机制会有更多的了解。如__init__, call, __new__等内置方法。

到此这篇关于Python装饰器的四种定义形式的文章就介绍到这了,更多相关Python装饰器内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Python装饰器的定义和使用详情

    目录 1.装饰器的定义 2.装饰器的通用类型的定义 3.多个装饰器同时装饰一个函数 4.多个装饰器同时装饰一个函数(二) 5.类装饰器使用方法 6.使用装饰器实现自动维护路由表 1.装饰器的定义 装饰器:给已有函数增加额外的功能的函数,本质上是一个闭包函数 特点: 1.不修改已有函数的源代码 2.不修改已有函数的调用方式 3.给已有函数增加额外的功能 4.代码执行时先解析装饰器 import time   # 装饰器原理 # def show(): #     n=0 #     for i i

  • Python使用自定义装饰器的示例详解

    在Python自动化测试中,使用自定义的装饰器来给测试方法传递测试数据: reader.py import csv import json from openpyxl import load_workbook from setting import DATA_DIR from os import path class Reader: @classmethod def read_excel(cls,xlname, min_row, max_row, min_col, max_col): xlnam

  • Python 装饰器原理、定义与用法详解

    本文实例讲述了Python 装饰器原理.定义与用法.分享给大家供大家参考,具体如下: Python 装饰器 一.何为装饰器 1.在函数中定义函数 在函数中定义另外的函数,就是说可以创建嵌套的函数,例子如下 def sayHi(name="hjj2"): print 'inside sayHi() func' def greet(): return 'inside greet() func' print(greet()) sayHi() #output # inside sayHi()

  • python如何定义带参数的装饰器

    本文实例为大家分享了python定义带参数装饰器的具体代码,供大家参考,具体内容如下 案例: 实现一个装饰器,用它来检查被装饰函数的参数类型. 需求: 装饰器可以通过函数,指明函数参数类型,进行函数调用的时候,传入参数,检测到不匹配时,抛出异常 如何解决这个问题? 先要获取函数的签名,并且获得装饰器中参数,然后把函数签名和装饰器中参数对应绑定 把调用函数时候传入的参数和函数签名进行绑定 把实参和装饰器中定义的数据进行类型比较,不匹配抛出异常 #!/usr/bin/python3 from ins

  • Python如何将装饰器定义为类

    问题 你想使用一个装饰器去包装函数,但是希望返回一个可调用的实例. 你需要让你的装饰器可以同时工作在类定义的内部和外部. 解决方案 为了将装饰器定义成一个实例,你需要确保它实现了 __call__() 和 __get__() 方法. 例如,下面的代码定义了一个类,它在其他函数上放置一个简单的记录层: import types from functools import wraps class Profiled: def __init__(self, func): wraps(func)(self

  • 详解Python装饰器的四种定义形式

    目录 前言 用函数装饰函数 用函数装饰一个类 用类定义装饰器,然后装饰一个函数 用类定义装饰器,然后装饰一个类 小结 前言 装饰器(decorator)在Python框架中扮演着重要角色,是Python中实现切面编程(AOP)的重要手段. aspect-oriented programming (AOP) ,在不改变代码自身的前提下增加程序功能 不改变代码自身,但需要在函数和类头上加一个标注(annotation),这个标注在Python里叫装饰器,在java里叫注解.在Python里,一共有四

  • 实例详解Python装饰器与闭包

    闭包是Python装饰器的基础.要理解闭包,先要了解Python中的变量作用域规则. 变量作用域规则 首先,在函数中是能访问全局变量的: >>> a = 'global var' >>> def foo(): print(a) >>> foo() global var 然后,在一个嵌套函数中,内层函数能够访问在外层函数中定义的局部变量: >>> def foo(): a = 'free var' def bar(): print(a)

  • 详解Python装饰器

    1. 定义 本质是函数,用来装饰其他函数,为其他函数添加附加功能 2. 原则 a. 不能修改被装饰函数的源代码 b. 不能修改被装饰的函数的调用方式 3. 实现装饰器知识储备 a. 函数就是变量 b. 高阶函数     i. 把一个函数当作实参传给另外一个函数,在不修改被装饰函数源代码情况下为其添加功能     ii. 返回值中包含函数名, 不修改函数的调用方式 c. 嵌套函数 高阶函数+嵌套函数==>装饰器 # Author: Lockegogo user, passwd = 'LK', '1

  • 详解Python装饰器 给你的咖啡加点料

    一.函数回顾 1.在python中函数是一等公民,函数也是对象.我们可以把函数赋予变量. def make_cofe(type): print('获得一杯 : {}'.format(type)) ​ get_cofe = make_cofe get_cofe('咖啡') ​ ####输出##### 获得一杯 : 咖啡 这个例子中,我们把函数make_cofe 赋予了变量 get_cofe,这样之后你调用 get_cofe,就相当于是调用函数 make_cofe(). 2.把函数当作参数,传入另一

  • 详解Python装饰器由浅入深

    装饰器的功能在很多语言中都有,名字也不尽相同,其实它体现的是一种设计模式,强调的是开放封闭原则,更多的用于后期功能升级而不是编写新的代码.装饰器不光能装饰函数,也能装饰其他的对象,比如类,但通常,我们以装饰函数为例子介绍其用法.要理解在Python中装饰器的原理,需要一步一步来.本文尽量描述得浅显易懂,从最基础的内容讲起. (注:以下使用Python3.5.1环境) 一.Python的函数相关基础 第一,必须强调的是python是从上往下顺序执行的,而且碰到函数的定义代码块是不会立即执行它的,只

  • 详解Python 装饰器执行顺序迷思

    探究多个装饰器执行顺序 装饰器是Python用于封装函数或代码的工具,网上可以搜到很多文章可以学习,我在这里要讨论的是多个装饰器执行顺序的一个迷思. 疑问 大部分涉及多个装饰器装饰的函数调用顺序时都会说明它们是自上而下的,比如下面这个例子: def decorator_a(func): print 'Get in decorator_a' def inner_a(*args, **kwargs): print 'Get in inner_a' return func(*args, **kwarg

  • 详解利用装饰器扩展Python计时器

    目录 介绍 理解 Python 中的装饰器 创建 Python 定时器装饰器 使用 Python 定时器装饰器 Python 计时器代码 其他 Python 定时器函数 使用替代 Python 计时器函数 估计运行时间timeit 使用 Profiler 查找代码中的Bottlenecks 总结 介绍 在本文中,云朵君将和大家一起了解装饰器的工作原理,如何将我们之前定义的定时器类 Timer 扩展为装饰器,以及如何简化计时功能.最后对 Python 定时器系列文章做个小结. 这是我们手把手教你实

  • 详解Python 实现 ZeroMQ 的三种基本工作模式

    简介 引用官方说法:ZMQ(以下 ZeroMQ 简称 ZMQ)是一个简单好用的传输层,像框架一样的一个 socket library,他使得 Socket 编程更加简单.简洁和性能更高. 是一个消息处理队列库,可在多个线程.内核和主机盒之间弹性伸缩. ZMQ 的明确目标是"成为标准网络协议栈的一部分,之后进入 Linux 内核".现在还未看到它们的成功.但是,它无疑是极具前景的.并且是人们更加需要的"传统" BSD 套接字之上的一 层封装.ZMQ 让编写高性能网络应

  • 详解Spring Security 中的四种权限控制方式

    Spring Security 中对于权限控制默认已经提供了很多了,但是,一个优秀的框架必须具备良好的扩展性,恰好,Spring Security 的扩展性就非常棒,我们既可以使用 Spring Security 提供的方式做授权,也可以自定义授权逻辑.一句话,你想怎么玩都可以! 今天松哥来和大家介绍一下 Spring Security 中四种常见的权限控制方式. 表达式控制 URL 路径权限 表达式控制方法权限 使用过滤注解 动态权限 四种方式,我们分别来看.  1.表达式控制 URL 路径权

  • 详解Python装饰器之@property

    一.property() 函数讲解 了解 @property 装饰器之前,我们首先要了解内置函数的 property(). class property(fget=None, fset=None, fdel=None, doc=None) 描述: 返回 property 属性. 参数说明: fget -- 获取属性值的函数. fset -- 设置属性值的函数. fdel -- 删除属性值函数. doc -- property 属性的文档字符串,如果没有给出 doc,则该 property 将拷贝

随机推荐