python装饰器

python装饰器其核心就是一个函数,类似于spring中的AOP。
通常来说,该函数接受被装饰的函数作为参数,执行某些操作后,返回该参数或者返回调用该参数的函数。
一般来说装饰器有下列几种用法:

1.在装饰时对被装饰的函数进行操作
def doc_decorate(func):
    func.__doc__ = "return the sum of @param x and @param y"
    return func


@doc_decorate
def foo(x, y):
    return x + y


if __name__ == '__main__':
    print foo.__doc__

结果

return the sum of @param x and @param y

这里装饰器对foo函数的_ doc_属性进行了修改

2.在函数执行时进行操作

验证参数类型

def decorate(func):
    def inner(x, y):
        if not isinstance(x, int) or not isinstance(y, int):
            raise TypeError("only accept integers as param")
        return func(x, y)
    return inner


@decorate
def foo(x, y):
    return x + y


if __name__ == '__main__':
    foo('1', 2)

执行foo(‘1’,2)将抛出TypeError
另外,如过运行help(foo)将打印函数inner的帮助信息

Help on function inner in module _ main_:
inner(x, y)

这是因为装饰器作用后变量foo的引用不再是原来的foo函数而是装饰器内inner函数
这是由于装饰器实际上语法与下列相同

foo = decorate(foo)

这里用@functools.wraps来解决这个问题

import functools


def decorate(func):
    @functools.wraps(func)
    def inner(x, y):
        if not isinstance(x, int) or not isinstance(y, int):
            raise TypeError("only accept integers as param")
        return func(x, y)
    return inner


@decorate
def foo(x, y):
    return x + y


if __name__ == '__main__':
    help(foo)

结果

Help on function foo in module _ main_:
foo(x, y)

3.带参数的装饰器
import functools


def decorate_with_param(*args, **kwargs):
    def decorate(func):
        @functools.wraps(func)
        def inner(x, y):
            print args             # 打印参数
            if not isinstance(x, int) or not isinstance(y, int):
                raise TypeError("only accept integers as param")
            return func(x, y)
        return inner
    return decorate


@decorate_with_param('1', '2')
def foo(x, y):
    return x + y


if __name__ == '__main__':
    print foo(1, 2)

结果

(‘1’, ‘2’)
3

4.装饰类的装饰器

重写类的_ repr _方法

def decorate(func):
    @functools.wraps(func)
    def override_repr(*args, **kwargs):
        func.__repr__ = lambda self:  "this is the class named " + func.__name__ # 重写类的_ _repr_ _方法
        return func(*args, **kwargs)
    return override_repr


@decorate
class Funny:
    def __init__(self):
        pass

    def __repr__(self):
        return "class"


if __name__ == '__main__':
    print Funny()

结果

this is the class named Funny

5.类型转换
def de(func):
    class task(object):
        def __call__(self, *args, **kwargs):
            return func(*args, **kwargs)
    return task()

@de
def fo(x, y):
    return x+y

if __name__ == '__main__':
    print fo(1, 2)   # 此时fo变量的引用为task实例

结果

3

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值