• 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") 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

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

    def test_wrapper2(func):
        def inner_wrapper():
            pass
    
        return inner_wrapper
    
    @test_wrapper2
    def func3():
        pass
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

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

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

    def A(func):
    	pass
    	
    @A
    def func():
    	pass
    	
    func()
    """
    就相当于是
    把func()的调用
    换成了A(func)(),故这里A函数返回的一定是一个可以被调用(call)的函数,否则会报错
    """
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    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")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

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

    another_keyword(another_keyword=1)(func)()
    
    • 1

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

    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")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

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

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

  • 相关阅读:
    中国深圳市服装行业深度分析及发展趋势研究报告
    夏天给宝宝开空调需要注意的几点
    CloudKit教程之由 CloudKit 公共数据库提供支持的示例 SwiftUI 定位应用程序(教程含源码)
    大数据生态安全框架的实现原理与最佳实践(下篇)
    steam搬砖项目,月利润9000+
    软考复习(二):操作系统
    一次Go项目进程重启故障问题排查
    机器学习知识总结 —— 15. 什么是支持向量机(对偶问题、核技巧)?
    堆排序算法---C语言实现(超详细解析!!!!)
    一篇学会JUC、JVM 吊打面试官!
  • 原文地址:https://blog.csdn.net/ZYM66/article/details/128035781