Python装饰器模式学习总结

                       

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

类比于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'
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

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


关于装饰器

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

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

def bar(func): print 'Bar' return func@bardef foo():    print "foo"# 其等价于:def foo():    print "foo"foo = bar(foo)
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

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

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

下面看一个实例:

import timedef 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: 2used time: 0mul result: 10上述代码中装饰器的调用等价于:add = function_performance_statistics(True)(add(1, 1))mul = function_performance_statistics(False)(mul(10))
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

写一个日志记录器

# 做一个loggerdef logging(filename="", level=0):    def wrapper(func):        def log(*args, **kwargs):            with open(filename, "a") as file:                line = "[LEVEL: {}] {}, {}\n".format(level, args, kwargs)                file.write(line)                file.close()            # 需要有返回值就return,否则就不用return            return func(*args, **kwargs)        return log    return wrapper@logging(filename="query.log", level=1)def query(msg):    print(msg, " be carried.")    return "`{}` has beed logged.".format(msg)print(query("select * from user where userid = 2614677"))
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

总结

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

           

再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值