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

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

  • 相关阅读:
    深度学习笔记(51) 基础知识
    ENVI:如何进行遥感图像的分类?(支持向量机模型)
    Java基础之《HTML5标签(1)》
    远距离WiFi无线传输方案,CV5200模组通信应用,无线自组网技术
    MySQL之双主双从读写分离
    【分布式应用】消息队列之卡夫卡 + EFLFK集群部署
    2014年下半年 系统架构设计师 下午论文
    智慧校园建设,需要哪些必要条件?
    LeetCode: 2. 两数相加
    大数据面试题(三):MapReduce核心高频面试题
  • 原文地址:https://blog.csdn.net/ZYM66/article/details/128035781