亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

Python中用Decorator來(lái)簡(jiǎn)化元編程的教程

系統(tǒng) 1758 0

少勞多得

Decorator 與 Python 之前引入的元編程抽象有著某些共同之處:即使沒(méi)有這些技術(shù),您也一樣可以實(shí)現(xiàn)它們所提供的功能。正如 Michele Simionato 和我在 可愛(ài)的 Python 專欄的早期文章 中指出的那樣,即使在 Python 1.5 中,也可以實(shí)現(xiàn) Python 類的創(chuàng)建,而不需要使用 “元類” 掛鉤。

Decorator 根本上的平庸與之非常類似。Decorator 所實(shí)現(xiàn)的功能就是修改緊接 Decorator 之后定義的函數(shù)和方法。這總是可能的,但這種功能主要是由 Python 2.2 中引入的 classmethod() 和 staticmethod() 內(nèi)置函數(shù)驅(qū)動(dòng)的。在舊式風(fēng)格中,您可以調(diào)用 classmethod(),如下所示:
清單 1. 典型的 “舊式” classmethod

            
class C:
  def foo(cls, y):
    print "classmethod", cls, y
  foo = classmethod(foo)


          

雖然 classmethod() 是內(nèi)置函數(shù),但并無(wú)獨(dú)特之處;您也可以使用自己的方法轉(zhuǎn)換函數(shù)。例如:
清單 2. 典型的 “舊式” 方法的轉(zhuǎn)換

            
def enhanced(meth):
  def new(self, y):
    print "I am enhanced"
    return meth(self, y)
  return new
class C:
  def bar(self, x):
    print "some method says:", x
  bar = enhanced(bar)


          

decorator 所做的一切就是使您避免重復(fù)使用方法名,并且將 decorator 放在方法定義中第一處提及其名稱的地方。例如:
清單 3. 典型的 “舊式” classmethod

            
class C:
  @classmethod
  def foo(cls, y):
    print "classmethod", cls, y
  @enhanced
  def bar(self, x):
    print "some method says:", x


          

decorator 也可以用于正則函數(shù),采用的是與類中的方法相同的方式。令人驚奇的是,這一切是如此簡(jiǎn)單(嚴(yán)格來(lái)說(shuō),甚至有些不必要),只需要對(duì)語(yǔ)法進(jìn)行簡(jiǎn)單修改,所有東西就可以工作得更好,并且使得程序的論證更加輕松。通過(guò)在方法定義的函數(shù)之前列出多個(gè) decorator,即可將 decorator 鏈接在一起;良好的判斷可以有助于防止將過(guò)多 decorator 鏈接在一起,不過(guò)有時(shí)候?qū)讉€(gè) decorator 鏈接在一起是有意義的:
清單 4. 鏈接 decorator

            
@synchronized
@logging
def myfunc(arg1, arg2, ...):
  # ...do something
# decorators are equivalent to ending with:
#  myfunc = synchronized(logging(myfunc))
# Nested in that declaration order


          

Decorator 只是一個(gè)語(yǔ)法糖,如果您過(guò)于急切,那么它就會(huì)使您搬起石頭砸了自己的腳。decorator 其實(shí)就是一個(gè)至少具有一個(gè)參數(shù)的函數(shù) ―― 程序員要負(fù)責(zé)確保 decorator 的返回內(nèi)容仍然是一個(gè)有意義的函數(shù)或方法,并且實(shí)現(xiàn)了原函數(shù)為使連接有用而做的事情。例如,下面就是 decorator 兩個(gè)不正確的用法:
清單 5. 沒(méi)有返回函數(shù)的錯(cuò)誤 decorator

            
>>> def spamdef(fn):
...   print "spam, spam, spam"
...
>>> @spamdef
... def useful(a, b):
...   print a**2 + b**2
...
spam, spam, spam
>>> useful(3, 4)
Traceback (most recent call last):
 File "
            
              ", line 1, in ?
TypeError: 'NoneType' object is not callable


            
          

decorator 可能會(huì)返回一個(gè)函數(shù),但這個(gè)函數(shù)與未修飾的函數(shù)之間不存在有意義的關(guān)聯(lián):
清單 6. 忽略傳入函數(shù)的 decorator

            
>>> def spamrun(fn):
...   def sayspam(*args):
...     print "spam, spam, spam"
...   return sayspam
...
>>> @spamrun
... def useful(a, b):
...   print a**2 + b**2
...
>>> useful(3,4)
spam, spam, spam


          

最后,一個(gè)表現(xiàn)更良好的 decorator 可以在某些方面增強(qiáng)或修改未修飾函數(shù)的操作:
清單 7. 修改未修飾函數(shù)行為的 decorator

            
>>> def addspam(fn):
...   def new(*args):
...     print "spam, spam, spam"
...     return fn(*args)
...   return new
...
>>> @addspam
... def useful(a, b):
...   print a**2 + b**2
...
>>> useful(3,4)
spam, spam, spam
25


          

您可能會(huì)質(zhì)疑,useful() 到底有多么有用?addspam() 真的是那樣出色的增強(qiáng) 嗎?但這種機(jī)制至少符合您通常能在有用的 decorator 中看到的那種模式。

高級(jí)抽象簡(jiǎn)介

根據(jù)我的經(jīng)驗(yàn),元類應(yīng)用最多的場(chǎng)合就是在類實(shí)例化之后對(duì)類中的方法進(jìn)行修改。decorator 目前并不允許您修改類實(shí)例化本身,但是它們可以修改依附于類的方法。這并不能讓您在實(shí)例化過(guò)程中動(dòng)態(tài)添加或刪除方法或類屬性,但是它讓這些方法可以在運(yùn)行時(shí)根據(jù)環(huán)境的條件來(lái)變更其行為。現(xiàn)在從技術(shù)上來(lái)說(shuō),decorator 是在運(yùn)行 class 語(yǔ)句時(shí)應(yīng)用的,對(duì)于頂級(jí)類來(lái)說(shuō),它更接近于 “編譯時(shí)” 而非 “運(yùn)行時(shí)”。但是安排 decorator 的運(yùn)行時(shí)決策與創(chuàng)建類工廠一樣簡(jiǎn)單。例如:
清單 8. 健壯但卻深度嵌套的 decorator

            
def arg_sayer(what):
  def what_sayer(meth):
    def new(self, *args, **kws):
      print what
      return meth(self, *args, **kws)
    return new
  return what_sayer


          


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 五月天婷婷免费视频观看 | 日本特黄a级高清免费大片18 | 亚洲欧美成人中文在线网站 | 久久久久久久久久免费视频 | 国产午夜精品一区二区三区 | 国产区综合另类亚洲欧美 | 特黄a大片免费视频 | 亚洲成人综合视频 | 国产精品欧美亚洲韩国日本 | 久久免费视屏 | 日韩欧美一区在线观看 | 中国jizz| 久操热久操 | 伊人久久色| 精品欧美一区二区三区在线 | 麻豆精品久久久一区二区 | 成人国产在线24小时播放视频 | 国产午夜精品一区二区三区嫩草 | 久久久久久久久免费视频 | 四虎影视永久在线精品免费播放 | 狠狠色狠狠色综合婷婷tag | 精品欧美一区二区三区在线 | 欧美在线成人午夜影视 | 五月婷婷之综合激情 | 国产自愉怕一区二区三区 | 夜夜夜夜夜夜爽噜噜噜噜噜噜 | 亚洲区视频 | 九九热在线视频播放 | 日本欧美在线播放 | 天天插夜夜操 | 欧美综合成人 | 亚洲网站视频 | 国产成人在线播放 | 七七久久综合 | 天天做天天爱天天怼 | 99re8免费视频精品全部 | 亚洲美女免费视频 | 亚洲国产欧美在线 | 日本三级日本三级人妇三级四 | 久久这里只精品国产99热8 | 国产在线91精品入口首页 |