美文网首页
[python]装饰器

[python]装饰器

作者: 不上火喝纯净水 | 来源:发表于2019-03-28 12:46 被阅读0次

装饰器是python中很好用的一个特性,我们看下面的方法装饰器

# 定义一个装饰器,对函数调用增加日志输出功能
def call_log(func):
    # 装饰输入的函数
    def func_wrapper(*args, **kw):
        print('will call func: %s' % func.__name__)
        return func(*args, **kw)
    # 返回装饰后的函数
    return func_wrapper

@call_log
def method1():
    print('calling method1')
上述装饰器的定义可以发现它是一个将函数作为参数并且内部定义一个新的函数作为返回值的结构,它是一个典型的高阶函数

装饰器也是可以携带参数的

# 定义一个带参数的装饰器,对函数调用增加日志输出功能
def call_log(param):
    # 返回一个装饰器
    def func_decorator(func):
        # 装饰输入的函数
        def func_wrapper(*args, **kw):
            print(param)
            print('will call func: %s' % func.__name__)
            return func(*args, **kw)
        # 返回装饰后的函数
        return func_wrapper
    return func_decorator

@call_log('test')
def method1():
    print('calling method1')

在网络上看到一道python题大致意思是【如何实现一个装饰器可以同时适用上面的2种情况】,其实如果我们对装饰器的原理以及高阶函数的应用很熟悉的话,那么这道题将很容易分析出来:

  • @call_log这种形式的装饰器是直接调用装饰器方法来修饰待的方法;
  • @call_log(x)这种形式的装饰器则是使用call_log(x)方法的返回值作为一个装饰器来修饰待装饰的方法;
所以我们最终定义的这个装饰器方法应该同时具备接收一个待装饰的方法作为参数接收若干个装饰变量作为参数的能力

按照这个思路该装饰器的最终实现如下:

def call_log(obj):
    # 如果参数是函数,则直接装饰该函数并返回
    if isinstance(obj, types.FunctionType):
        def func_wrapper(*args, **kw):
            print('will call %s:' % obj.__name__)
            return obj(*args, **kw)
        return func_wrapper
    else:
        # 返回一个装饰器
        def func_decorator(func):
            def func_wrapper(*args, **kw):
                print(obj)
                print('will call func: %s' % func.__name__)
                return func(*args, **kw)
            return func_wrapper
        return func_decorator

# 不带参数装饰方法
@call_log
def method1():
    print('calling method1')

# 携带带参数装饰方法
@call_log('test')
def method2():
    print('calling method2')

method1()
method2()

''' 
输出如下
will call method1():
calling method1
test
will call func: method2()
calling method2
'''
上述实现中通过对call_log方法的参数的类型来判断它的调用出是不带参数的装饰器调用还是带参数的装饰器调用从而动态返回内部的实现。
事实上带参数的装饰器@call_log('test')完全可以拆分为两步,它等价于下面的代码:
# 先返回一个装饰器函数
decorator = call_log('test')
# 在用返回的装饰器来装饰method2
@decorator
def method2():
    print('calling method2')

总结

  • 属性装饰器可用来定义的私有成员变量的setter和getter方法达到封装的内部实现的目的;
  • 类装饰器和方法装饰器可以装饰方法,为方法添加额外的代码逻辑,通常用在诸如添加日志,添加时间戳,添加监控。
  • 装饰器有点类似于其他语言中AOP的概念;
  • 装饰器的本质是对函数式编程中的高阶函数的应用;

相关文章

  • 装饰器模式

    介绍 在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/wuufbqtx.html