IronPython0.9.3发布了 —— 介绍一下Decorator

        上周五就已经从IronPython Team发出的Mail中得知IronPython又发布了新版本——0.9.3。慵懒的周末让偶怠慢了跟踪报道,真不好意思了。不过也正好有了时间来酝酿一下这篇Post该写些什么,而不致于空洞无物。
        在短短的不到一个月的时间里就发布了新的版本,改动果然如我猜想的那样并不是很大,主要是集中在修复与Closure相关的bugs。大家从IronPython的Workspace中可以看到Release Notes并且下载到最新的版本。虽然这次的改动并不算太大,而且与我最近关注的Python特性也没有太大关系,但是一个看得见的小改进让我开心不已——Decorator的bug修复了,几个原来无法正确运行的程序总算让我看到了期待的运行结果!0.9.2中实现的Decorator给我的感觉就像是半成品,让我没了兴趣。而新版本中的Decorators总算焕然一新,让我精神为之振奋,而Decorator也顺理成章地成为了这篇Post的主角。
        Decorator是Python2.4中引入的新特性,它的原意是为了能够实现一般OO语言中的static方法或者说是类方法。然而在实际应用当中,它的应用范围则是非常广。为了了解Decorator,我们先来看一段简单的代码:

None.gif 第一部分:
None.gif
>>>  def decorate(func):
None.gifdot.gif     print func.func_name
None.gifdot.gif
None.gif
>>>  @decorate
None.gifdot.gif def test():     
None.gifdot.gif     print 
"test function"
None.gifdot.gif          #以上代码等价于 decorate(test)
None.giftest
None.gif
None.gif
>>> test()   # test这个function在全局范围不可见
None.gifTraceback (most recent call last):
None.gif   at 
<shell>
None.gifAttributeError: 
'NoneType' object has no attribute '__call__'
None.gif
None.gif------------------------------------------------
None.gif第二部分:
None.gif
>>>  def decorate(source, dest):
None.gifdot.gif     print source, dest
None.gifdot.gif     def wrapper(func):
None.gifdot.gif         pass
None.gifdot.gif     
return  wrapper
None.gifdot.gif
None.gif
>>> @decorate("source""dest" )
None.gifdot.gif def test():
None.gifdot.gif     print 
"test function"
None.gifdot.gif          #以上代码等价于 decorate(
"source""dest")(test)
None.gifsource dest
None.gif

从以上代码可以看出Decorator本身就是一个function,它在语法上的定义跟一般function是没有区别的;Decorator在使用时通过@来表示;被Decorator修饰的实体是function对象。虽然Decorator在语法上与一般的function并无二致,但是其定义的内容和参数则是有考究的。我把Decorator看作是一个可以接受function对象为参数的特殊function,Decorator在定义的时候是必须带参数的。Decorator在使用的时候有两种方式,带参数和不带参数。使用方式不同也决定了Decorator在定义上的不同。当Decorator在使用的时候不带参数,那么其定义就有且仅有一个参数,这个参数所对应的实参就是被修饰的function,如以上代码第一部分所示;当Decorator在使用的时候带参数的话,那么其定义所包含的参数个数与使用时是一致。在这种情况下,Decorator定义的限制就比较多了,它必须包含function,并且要将该function作为Decorator的返回值,如以上代码中第二部分所示。被Decorator修饰的function就像是匿名函数一样,虽然有function名,却无法通过function名调用到该function。因此,以上的示例代码是没有什么实际意义的,只是为了方便说明问题。
        一个真正有实际作用的Decorator通常都是对传入的function对象进行处理后并返回或者创建一个新的function对象并返回。不管怎样,一个有用的Decorator都会返回一个function对象,这样才能在使用了Decorator之后可以调用到一个修饰后的function。具体的可以参考limodou所写的decorator的使用一文中decorator函数的定义部分。
        回头再看看自己写的东西,似乎越说越复杂了,其实Decorator是一个很简单的概念,它只不过是一个可以修改function的function罢了。以下是不使用Decorator与使用Decorator来实现相同效果的代码,大家可以从中看到Decorator只是一个简单概念的演化而已。

None.gif
None.gif
>>>  def test():
None.gifdot.gif     pass
None.gifdot.gif
None.gif
>>>  def decorate(func):
None.gifdot.gif     func.author 
= "FantasySoft"
None.gifdot.gif     
return  func
None.gifdot.gif
None.gif
>>>  decorate(test)
None.gif
<function test at 0x000000000000002F>
None.gif
>>>  test.author
None.gif
'FantasySoft'
None.gif-------------------------------------------  
None.gif
>>>  def decorate(func):
None.gifdot.gif     func.author 
= "FantasySoft"
None.gifdot.gif     
return  func
None.gifdot.gif
None.gif
>>>  @decorate
None.gifdot.gif def test():
None.gifdot.gif     pass
None.gifdot.gif
None.gif
>>>  test.author
None.gif
'FantasySoft'
None.gif

        把修改其他function的function独立出来,作用并不是那么的明显。但是这样做可以将一些公共模块归类为Decorator,使得代码组织更为清晰。而在多层函数调用的情况下,使用Decorator的语法也会显得简单明了。其他的Motivation,大家可以参考Decorators for Functions and Methods(PEP 318) 。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值