• 关于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规定的内容。
  • 相关阅读:
    HDU 1985 Conversions
    HDU 1708 Fibonacci String
    HDU 3501 Calculation 2
    HDU 4163 Stock Prices
    HDU 2391 Filthy Rich
    HDU 1996 汉诺塔VI
    HDU 2824 The Euler function
    HDU 1787 GCD Again
    HDU 2393 Higher Math
    HDU 1286 找新朋友
  • 原文地址:https://www.cnblogs.com/gjwork/p/4432489.html
Copyright © 2020-2023  润新知