说在前边
装饰器作为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__方法,也就是说,这个类的实例可以像函数一样被调用,我们只需要实例化这个类就可以当做装饰器使用了。
这样做的好处是,我们在实例化类的时候,可以传入初始化的参数,就不用向上边那样对函数进行层层闭包了。
到此这篇关于Python装饰器详细介绍的文章就介绍到这了,更多相关Python装饰器内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!