浅谈python装饰器

装饰器是 Python 中比较重要的一个概念,它是基于装饰器模式实现的,装饰器模式是一种结构型设计模式,它允许向现有的一个对象添加新的功能,而又不改变其结构。

Python 中,装饰器是一个函数或者是一个类,它的功能是让其他函数或者类在不改变内部结构的情况下添加新的功能,通常用于切面需求,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景,它的返回值也是一个函数。

通常,我们会使用高阶函数来实现装饰器,可以接收函数作为参数的函数我们就称其为高阶函数。当然,也可以使用类来实现装饰器,那就是类装饰器。

1. 函数装饰器

下面是常见的函数装饰器的结构:

from functools import wraps

def decorator(func):
    @wraps(func)  # 将func函数的元信息拷贝到wrapper函数中
    def wrapper(*args, **kwargs):
        print('decorator!!!!')
        # do everything  # 在函数func执行前执行
        return func(*args, **kwargs)
    return wrapper

@decorator
def test():
    '''一个不允许修改的函数哦!'''
    # do something
    return 'my test'

运行上面的test函数:

In  [1]:  test()
decorator!!!
Out [1]:  'my test'

使用 @ 语法,将装饰器 decorator 装饰在函数 test 上面时,会把 test 作为一个参数传给 decorator ,返回新的函数 wrapper ,在装饰器内部的 wraps 用于把 func 的文档字符串以及函数名拷贝到内部函数 wrapper 上。此时,当我们调用 test 函数的时候,实际上调用的是 wrapper 函数。这样,在不修改函数 test 内部代码的情况下添加了我们想要添加的功能。
对于函数 test 的参数,在装饰器 decorator 中,通过参数打包的方式传给 func

2. 装饰器参数

某些时候,可能需要给装饰器传参数,那么需要再定义一层函数,使用 @ 语法装饰函数时传给装饰器参数。

from functools import wraps

def outter(param):
    def decorator(func):
        @wraps(func)  # 将func函数的元信息拷贝到wrapper函数中
        def wrapper(*args, **kwargs):
            print('装饰器参数: ', param)
            print('decorator!!!!')
            # do everything  # 在函数func执行前执行
            return func(*args, **kwargs)
        return wrapper
    return decorator

@outter('for test')
def test():
    '''一个不允许修改的函数哦!'''
    # do something
    return 'my test'
3. 类装饰器

装饰器也可以是一个类,类装饰器主要依赖于 __call__ 方法:

class Decorator(object):
    def __init__(self, func):
        self.__func = func
    def __call__(self, *args, **kwargs):
        # do something
        return self._func(*args, **kwargs)

@Decorator
def test():
    '''一个不允许修改的函数哦!'''
    # do something
    return 'my test'
4. 装饰器的顺序

一个函数如果被多个装饰器装饰,则按照先里后外的顺序装饰:

@decorator3
@decorator2
@decorator1
def test():
    pass

上面的代码相当于:

func = decorator3(decorator2(decorator1(test)))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值