美文网首页首页推荐程序员
Python装饰器模式学习总结

Python装饰器模式学习总结

作者: 尽情的嘲笑我吧 | 来源:发表于2017-10-07 08:06 被阅读0次

    装饰器模式,重点在于装饰。装饰的核心仍旧是被装饰对象。

    类比于Java编程的时候的包装模式,是同样的道理。虽然概念上稍有不同但是原理上还是比较相近的。下面我就来谈一谈我对Python的装饰器的学习的一点心得吧。


    关于作用域

    Python作用域 体现在LEGB中:

    • L:local 函数内部
    • E: enclosing 函数内部和内置函数之间
    • G:global 全局性质,有命名空间的限制
    • B:build-in 内置函数,由python解释器管理

    学过编程的人一眼就可以看得出来大致是什么意思,所以这里不再叙述。


    关于闭包

    关键在于理解Python中闭包的概念。说白了,闭包就是函数里面又定义了函数,这就是闭包了。(呵呵,断章取义一下。可能说法不恰当)。如下:

    def func1():
        print 'func1 is running'
        def in_func1():
            print 'in_func1 is running'
            return in_func1
        print 'over'
    
    

    简单的一个闭包的实现,就差不多是这个样子的。我们需要注意的就是要将内部函数当成一个对象来返回(Python中函数其实就是一个对象,我们可以通过type来进行验证)。
    这段代码执行的流程是先执行func1,然后执行func2,并且将func2作为一个属性返回给func1.这样我们可以再次的得到func2的内容。这就是闭包!


    关于装饰器

    类比Java中那么多的模式,比如ServletRequest被装饰成了HttpServletRequest。Python中也有很多这样被装饰的例子。如CookieJar被装饰成了MozillaCookieJar等等。实现的功能就是被装饰对象的功能得到了增强,完成的效果也大大大的比未装饰之前好了。这就是装饰的好处。
    下面就来看一看Python中怎么来实现装饰器吧。

    核心:借助于@符号,即可。

    def bar():
        print 'Bar'
    
    @bar
    def foo():
        print "foo"
    # 其等价于:
    def foo():
        print "foo"
    foo = bar(foo)
    

    代码执行的流程:
    先执行@对象,也就是一个函数。其返回值就是一个内置函数,只不过这个内置函数是得到了装饰的被装饰对象(这里是foo函数),我们可以理解为:

    装饰器,其本身接收一个函数对象作为参数,然后做一些工作后,返回接收的参数,供外界调用。

    下面看一个实例:

    import time
    
    def function_performance_statistics(trace_this=True):
        if trace_this:
           def performace_statistics_delegate(func):
                def counter(*args, **kwargs):
                    start = time.clock()
                    func(*args, **kwargs)
                    end =time.clock()
                    print 'used time: %d' % (end - start, )
                return counter
        else:
           def performace_statistics_delegate(func):
                return func
        return performace_statistics_delegate
    
    @function_performance_statistics(True)
    def add(x, y):
        time.sleep(3)
        print 'add result: %d' % (x + y,)
    
    @function_performance_statistics(False)
    def mul(x, y=1):
        print 'mul result: %d' % (x * y,)
    
    add(1, 1)
    mul(10)
    上述代码想要实现一个性能分析器,并接收一个参数,来控制性能分析器是否生效,其运行效果如下所示:
    add result: 2
    used time: 0
    mul result: 10
    上述代码中装饰器的调用等价于:
    add = function_performance_statistics(True)(add(1, 1))
    mul = function_performance_statistics(False)(mul(10))
    

    总结

    Python装饰器的核心就是装饰,实质就是被装饰函数性能的增强。

    相关文章

      网友评论

        本文标题:Python装饰器模式学习总结

        本文链接:https://www.haomeiwen.com/subject/nmbdyxtx.html