Python装饰器探究

说在前边

装饰器作为Python中的一个比较实用的东西,在我们日常库的使用过程中经常使用。但是其细节问题我们却常常忘记考虑,本文章就此问题写建装饰器代码来进行一步一步分析。


装饰器实验

1.我们常见的装饰器使用方式

from functools import wraps

def test_wrapper(func):
    @wraps(func)
    def inner_wrapper():
        print("Use inner_wrapper")
        func()

    return inner_wrapper


@test_wrapper
def func2():
    print("Use func2") 

2.装饰器可以进一步简化,留下最重要的部分

def test_wrapper2(func):
    def inner_wrapper():
        pass

    return inner_wrapper

@test_wrapper2
def func3():
    pass

调用func3()发现输出为空。
那我们便可以看出装饰器的实际运作方式

python解释器会call这个被@的函数名称,并向其中传入被装饰函数名称,例

def A(func):
	pass
	
@A
def func():
	pass
	
func()
"""
就相当于是
把func()的调用
换成了A(func)(),故这里A函数返回的一定是一个可以被调用(call)的函数,否则会报错
"""

3.研究深入,向装饰器中传入值

from functools import wraps


# 在装饰器中使用额外参数
def another_keyword(another_keyword=None):
    def test_func(func):
        @wraps(func)
        def func_wrapper():
            if another_keyword == 1:
                print("Use another_keyword")
            else:
                print("Not use another_keyword")
            print("Using func_wrapper")
            func()

        return func_wrapper

    return test_func

@another_keyword(another_keyword=1)
def func():
    print("Use func")

根据上方的分析,我们这次在调用func这个函数的时候就相当于以下流程

another_keyword(another_keyword=1)(func)()

可能有点复杂,需要再进行思考,不过接下来我们会使用一种更适合传参的装饰器

4.更加强大,用类实现装饰器

from functools import wraps


class cls_wrapper(object):
    def __init__(self):
        pass

    def __call__(self, func):
        @wraps(func)
        def inner_wrapper():
            func()

        return inner_wrapper
                
@cls_wrapper()
def func4():
    print("Use func4")

在一个类中,我们定义了__call__方法,也就是说,这个类的实例可以像函数一样被调用,我们只需要实例化这个类就可以当做装饰器使用了。
这样做的好处是,我们在实例化类的时候,可以传入初始化的参数,就不用向上边那样对函数进行层层闭包了。

今天的探究就到这里!谢谢大家观看!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值