python高级知识之装饰器

一、装饰器函数

装饰器设计模式的作用:用装饰器写的代码优雅、在不更改函数的基础上为函数增加额外的功能

1、不带参数

def add_hold(fun):
    def wrap():
        return '<a>' + fun() + '</a>'
    return wrap


@add_hold
def test():
    return "hello"
if __name__ == '__main__':
    print(test())
-----输出结果----------
<a>hello</a>

2、带参数

def log(filename: str):
    print(filename)
    def inner(fun):
        def wrapper(*args, **kwargs):
            return fun(*args, **kwargs)
        return wrapper
    return inner

@log(filename='xxxx.log')
def f(x, y):
    return x + y


if __name__ == '__main__':
    print(f(1, 2))
-----输出结果----------
xxxx.log
3

其实装饰器带参数就是在原来不带参数的外层又加了一层。

3、装饰器中的@

函数装饰器里的@可以大致理解为调用其后面紧接的对象的__call__()方法,所以一个对象能不能加(),取决于改对象有没有__call__属性

二、类装饰

1、不带参数

class A:
    def __init__(self, fun):
        self.fun = fun

	# __call__当对一个对象加()进行调用时,此方法会自动执行
    def __call__(self, *args, **kwargs):   
        pass
@A
def f(x, y):
    pass


if __name__ == '__main__':
    f(1, 2)
    # a=A(f)  注意:类和函数,直接加括号是可以的 
    # a(1,2)   但是由类创建的对象,一般不能加括号的   TypeError: 'A' object is not callable

2、带参数

from functools import wraps
class PrintAfterExecutionDecoratorClass:
    def __call__(self, func):
        @wraps(func)
        def wrapped_func(*args, **kwargs):
            ret = func(*args, **kwargs)
            print(ret)
            return ret
        return wrapped_func

@PrintAfterExecutionDecoratorClass()
def work_c(i):
    return i+1

三、@wraps的作用

@wraps装饰器的作用,就是在调用函数的时候,使被装饰函数的__name__属性不被装饰器所影响

加@wraps(fun)装饰器

def add_hold(fun):
    @wraps(fun)
    def wrap():
        return '<a>' + fun() + '</a>'
    return wrap


@add_hold
def test():
    print(test.__name__)
    return "hello"
if __name__ == '__main__':
    print(test())
-----输出结果----------
test
<a>hello</a>

不加@wraps(fun)装饰器

def add_hold(fun):
    # @wraps(fun)
    def wrap():
        return '<a>' + fun() + '</a>'
    return wrap


@add_hold
def test():
    print(test.__name__)
    return "hello"
if __name__ == '__main__':
    print(test())
-----输出结果----------
wrap
<a>hello</a>

通过上述2个例子可以看出,当加了@wraps(fun)装饰器后,打印的__name__依然是原函数的,而不是装饰器内的函数名称。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

克里斯蒂亚诺·罗纳尔达

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值