美文网首页
Python装饰器

Python装饰器

作者: ericsaid | 来源:发表于2017-09-05 12:18 被阅读0次

Python装饰器

  1. 装饰器的本质是什么?

装饰器等价于高阶函数,形如myfunc=decorator(myfunc),接受函数或类作为输入,以函数或类作为输出。在@语法糖中,并没有要求输出为一个函数或者类。即

def decorator(func):
      return None

@decorator
def foo():
    pass

也可以作为@decorator语法装饰函数或类。
所以,可以将装饰器当成是一个接受函数或类为输入的函数即可。

  1. 装饰器的使用场景
  • 插入日志
  • 性能测试
  • 事务处理
  • 权限认证
  • 修改传入参数/参数校验
  • 结果预处理
  • 截断函数的执行
  1. 编写不带装饰器参数的装饰器
def decorator(func):
  # do something when decorator called
    def _deco(*args, **kw):
        # do something before func called
        ret = func(*args, **kw)
        # do something after func called
        return ret
    return _deco

@decorator
def myfunc(*args, **kw):
    print "myfunc called"
    return True

内部函数“_deco”和myfunc的参数结构需要一致,当然不是要求形式上的一致。如参数为类的装饰器,如下

def singleton(cls):
    # do something when decorator called
    instances = {}

    def _getinstance(*args, **kw):
        if cls not in instances:
            instances[cls] = cls(*args, **kw)
        return instances[cls]
    return _getinstance

@singleton
class Myclass(object):
    def __init__(self, *args, **kw):
        pass

以上示例为构建单例模式的装饰器版本。

  1. 编写带装饰器参数的装饰器
    带参数的装饰器,等价于形如myfunc=decorator(a, b)(myfunc)的函数调用。decorator(a, b)返回一个不带装饰器参数的装饰器,即过程为:decorator1 = decorator(a, b) ;myfunc = decorator1(myfunc)。形式上多了一层函数,不过也可以使用柯里化的方式构建decorator1。如下例:
from functools import partial

def decorator(a, func):
    # do something when decorator called
    def _deco(*args, **kw):
        # do something before func called
        ret = func(*args, **kw)
        # do something after func called
        return ret
    return _deco
# or

def decorator_out(*args, **kwargs):
    # do something when decorator_out called with parameters
    def _outer(func):
        # do something when decorator_out called
        def _deco(*arg, **kw):
            # do something before func called
            # of course `*args` or `**kwargs`
            ret = func(*arg, **kw)
            # do something after func called
        return _deco
    return _outer

@partial(decorator, "param1")
def myfunc():
    print "myfunc"

@decorator_out("params1")
def myfunc1():
  print "myfunc1"
  1. functools.wraps
    因为Python中__name____doc__等metadata是在函数定义中生成的,而无法在执行过程中生成,所以myfunc=decorator(myfunc)执行之后,myfunc的metadata会发生变化,如myfunc.__name__,解决方案是装饰器中,加上functools.wraps。如上例:
from functools import wraps

def decorator_out(*args, **kwargs):
    # do something when decorator_out called with parameters
    def _outer(func):
        # do something when decorator_out called
        @wraps(func)
        def _deco(*arg, **kw):
            # do something before func called
            # of course `*args` or `**kwargs`
            ret = func(*arg, **kw)
            # do something after func called
            return ret
        return _deco
    return _outer

相关文章

  • 装饰器模式

    介绍 在python装饰器学习 这篇文章中,介绍了python 中的装饰器,python内置了对装饰器的支持。面向...

  • python中的装饰器

    python装饰器详解 Python装饰器学习(九步入门) 装饰器(decorator) 就是一个包装机(wrap...

  • [译] Python装饰器Part II:装饰器参数

    这是Python装饰器讲解的第二部分,上一篇:Python装饰器Part I:装饰器简介 回顾:不带参数的装饰器 ...

  • Python中的装饰器

    Python中的装饰器 不带参数的装饰器 带参数的装饰器 类装饰器 functools.wraps 使用装饰器极大...

  • Python进阶——面向对象

    1. Python中的@property   @property是python自带的装饰器,装饰器(decorat...

  • Python 装饰器填坑指南 | 最常见的报错信息、原因和解决方

    Python 装饰器简介装饰器(Decorator)是 Python 非常实用的一个语法糖功能。装饰器本质是一种返...

  • Python装饰器

    Python装饰器 一、函数装饰器 1.无参装饰器 示例:日志记录装饰器 2.带参装饰器 示例: 二、类装饰器 示例:

  • python3基础---详解装饰器

    1、装饰器原理 2、装饰器语法 3、装饰器执行的时间 装饰器在Python解释器执行的时候,就会进行自动装饰,并不...

  • 2019-05-26python装饰器到底是什么?

    装饰器例子 参考语法 装饰器是什么?个人理解,装饰器,是python中一种写法的定义。他仍然符合python的基本...

  • 2018-07-18

    Python装饰器 装饰,顾名思义,是用来打扮什么东西的。Python装饰...

网友评论

      本文标题:Python装饰器

      本文链接:https://www.haomeiwen.com/subject/treujxtx.html