没有为坚持到底努力过,智慧无从谈起。因为过程会获得阅历,而内容和结果都会忘记。

关于python装饰器的理解

再看了很多装饰器代码解释之后,懵懂的我,突然顿悟。主要参考

http://pythonmap.iteye.com/blog/1682696

http://www.cnblogs.com/rhcad/archive/2011/12/21/2295507.html

 

其实这两个参考开始都看不下去。完全不懂呀。折磨时候,实验代码,随便折腾,竟然让我顿悟了。抓到精髓了,再看就简单了。还有个问题没有解决,就是装饰器的用处。主要参考http://www.cnblogs.com/rollenholt/archive/2012/05/02/2479833.html 没理解下去。回头再看。

装饰器精髓:扮相 a,假演员 b,真演员 zhidou。     扮相必须且只能携带一个参数,用来接收假演员回传,真假演员必须带同个数参数。只能执行假演员规定动作。

某戏台要找出演《智斗》,演员要化妆成阿庆嫂的模样,那么就需要一个是准备阿庆嫂的扮相,另一个是找演员。装饰器的精髓就是这个。

>>> def a(m):    #这个a就是阿庆嫂的扮相,这里的参数m就是传入的真演员。
...   print "hello"    #迷惑敌人
...   def b():          #假设演员是 b 
...     return "A Qing Sao"#这个是演员在这部戏里面需要做的事情
...   print "world"    #迷惑敌人
...   return b          #这个 b 就是演员,把 b 塞到 a 的扮相下
... 

#上面就定义好了阿庆嫂的扮相和演员要做的事情

>>> @a      #这个表示下面出场的是阿庆嫂
... def zhidou():  #出演的演员名字是zhidou()
...   print "Diao De Yi"   #迷惑敌人
...   return "Sha Jia Bang"   #迷惑敌人
... 
hello     #迷惑敌人
world    #迷惑敌人

>>> zhidou()    #大幕拉开,演员zhidou已经化好妆上台,开始表演了
'A Qing Sao'     #看到了吧,输出只有规定好的动作,其他的都是浮云。


分析上面的代码,其中“迷惑敌人”的部分不用理,去掉,剩下的精髓就是阿庆嫂的扮相 a 和假定的演员 b 以及最后出演的真实的演员 zhidou 这三个部分。

其中扮相 a 必须携带一个参数,而且只能携带一个参数,这个参数是用来接收最后假定的演员 b ,在扮相 a 的面具下塞入 b。

还要有一个真实演员 zhidou,这就行了。简化代码。 而真正演员要做的事情,就是b里面规定的内容,其他地方无论是什么都是在开演前迷惑观众,宣传造势用的。

真正开演了,就做一件事情,就是b里面规定的事情。

def a(m):   #阿庆嫂扮相

     def b(): pass   #演员要做的事情

     return b    #把 b 塞到 阿庆嫂的扮相下

@a              #按照 a 的标准打扮的说明文字

def zhidou(): pass   #真演员开始化妆

zhidou()   #真演员开演

 

上面举例是演员 b 不带参数的,那么真演员 zhidou 也要不带参数。

如果 b 带着参数,那么 zhidou 也要带相同的参数

这样才可以演嘛。

但是无论怎么变, 扮相 a 里面只能带一个参数,而且只能带一个,返回值,也必须是这个假演员。

那么这个装饰器的作用是什么呢? 目前看是可以按不同扮相打扮真演员。

比如

@a

@A

def zhidou():pass

也就是同时有几个扮相打扮真演员。

具体打扮成什么样就看实际应用了。这里只是一个理解。

下面是带参的模样。迷惑部分就不写了,只写有用部分。可以带几个参数,现在设置只带一个参数。还可以b(x,y)等等。

def a(m):

  def b(x): return x+x

  return b

@a

def zhidou(y): return "hello"

 zhidou(3)  #运行结果就是一个6,没有输出任何“hello”。 这里又加了一个迷惑部分“hello”,只是为了更清楚,这不部分,无论写成什么,都不会起作用。

所以,请记住,装饰器的三大组成,扮相,假演员,真演员。 扮相必须带参数,用来接收假演员返回。真假演员必须佩带相同的参数。

还是挺高兴的。编程时候记住三个词,扮相、假演员、真演员。其他的就随手拈来。理解了精髓,可以看别人代码,慢慢学习。

附上 阿庆嫂 扮相一张,振奋一下昏昏欲睡的下午精神。

但是注意的是,上面例子中的真演员的动作忽略没有执行。那么如何执行真演员的动作呢?第二个精髓:装饰器只能执行假演员规定动作。扮相携带的参数,就是真演员函数,因为只能执行假演员规定的动作,所以要把真演员函数放到假演员函数中执行。

阿庆嫂

 

又经过了学习,参考了www.2cto.com/kf/201410/345585.html/将装饰器实际应用结合理解如下:

上面的扮相,真假演员的理解中,真演员规定的动作并没有执行,只是执行了假演员执行的动作。那么现在要加进去真演员的动作。

def a(m):

    def b(x,y):

        print "hello",m(x,y)   #这里把真演员的动作调入

    return b

@a

def k(x,y):

  return “%s wolaile %s” % (x,y)

运行 k("xiaoq","world") 结果为   hello xiaoq wolaile world    这样就将真假演员的动作都合在一起了。这样的 a 扮相叫做装饰器,借用设计假演员的动作,包装真演员。同时还不遗漏真演员的动作。这样真演员中的函数部分就不是迷惑敌人的用处,就可以使用了。

所以现在可以学着使用装饰器。一个场合是给真演员加点附加的运算。主要设计是放在b里面

举例

>>> class C(object):
...   def __init__(self,x,y):
...     self.name=x
...     self.language=y
...   def show(self):
...     print self.name,"+++",self.language
## 上面定义了一个类 C

>>> def a(m):
...   def b(x,y):
...     kk=m(x,y)    #运行了真演员的动作,获取返回信息
...     print "hello",kk[0],kk[1]    #设计真演员动作
...   return b
... 
>>> @a
... def k(x,y):    #真演员动作
...   c=C(x,y)
...   return c.name,c.language    #把信息返回供扮相 a 设计。
... 
>>> k("xiaoq","China")
hello xiaoq China    #记住一点,运行的一定只有 b 里面规定的内容,其他都是浮云。

好了,现在真假演员如何包装的已经看懂了,应用也了解了,可以去看别人代码了。 记住一点,扮相带参,真假演员,执行的是指假演员规定的动作。

 

注意装饰器和内建嵌套函数的区别。 内建嵌套函数不常用,外建嵌套函数常用,其实单独定义一个函数A,然后在定义另外一个函数B的时候,使用这个函数A而已。

python多用类函数,模块函数。很少使用自定义的内建嵌套函数。基本没有。所以这里注意和内建嵌套函数区分开。

 

但是有一种嵌套函数的闭包特性  http://www.jb51.net/article/55533.htm

>>> def test():
...   a={'name':'wyj'}
...   def f():
...     return a['name']
...   return a,f
... 
>>> a,f =test()
>>> f()
'wyj'
>>> a
{'name': 'wyj'}

>>> a['name']='weklj'   #指定了a的修改

>>> f()    #f的值也跟着改了。 好奇怪。这里需要研究一下。待定。
'weklj'

#想象中,也许,a和f在赋值test()的时候就已经按照test的规则规定了它们的关系,潜藏着某种运算规则,
所以,a改了,f也随着改了。从赋值 a,f=test() 开始,就决定了a和f之间的某个法则,就是test规定的内容。

 

posted @ 2015-04-16 16:34  嬉荒随毁  阅读(268)  评论(0编辑  收藏  举报
所有的苦难为的就是那份历练,丰富人生,参透世事 勤奋耕耘,春秋自至