亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費(fèi)注冊(cè) 查看新帖 |

Chinaunix

  平臺(tái) 論壇 博客 文庫(kù)
最近訪問(wèn)板塊 發(fā)新帖
查看: 2596 | 回復(fù): 1
打印 上一主題 下一主題

Python多重裝飾器 [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報(bào)告]
發(fā)表于 2015-07-08 15:08 |只看該作者 |倒序?yàn)g覽
多重裝飾器,即多個(gè)裝飾器修飾同一個(gè)對(duì)象【實(shí)際上并非完全如此,且看下文詳解】

1.裝飾器無(wú)參數(shù):
  1. >>> def first(func):
  2.     print '%s() was post to first()'%func.func_name
  3.     def _first(*args,**kw):
  4.         print 'Call the function %s() in _first().'%func.func_name
  5.         return func(*args,**kw)
  6.     return _first


  7. >>> def second(func):
  8.     print '%s() was post to second()'%func.func_name
  9.     def _second(*args,**kw):
  10.         print 'Call the function %s() in _second().'%func.func_name
  11.         return func(*args,**kw)
  12.     return _second


  13. >>> @first
  14. @second
  15. def test():return 'hello world'

  16. test() was post to second()
  17. _second() was post to first()
  18. >>> test()
  19. Call the function _second() in _first().
  20. Call the function test() in _second().
  21. 'hello world'
  22. >>>
復(fù)制代碼
實(shí)際上它是相當(dāng)于下面的代碼:
  1. >>> def test():
  2.     return 'hello world'

  3. >>> test=second(test)
  4. test() was post to second()
  5. >>> test
  6. <function _second at 0x000000000316D3C8>
  7. >>> test=first(test)
  8. _second() was post to first()
  9. >>> test
  10. <function _first at 0x000000000316D358>
  11. >>> test()
  12. Call the function _second() in _first().
  13. Call the function test() in _second().
  14. 'hello world'
  15. >>>
復(fù)制代碼
2.裝飾器有參數(shù):
  1. >>> def first(printResult=False):
  2.     def _first(func):
  3.         print '%s() was post to _first()'%func.func_name
  4.         def __first(*args,**kw):
  5.             print 'Call the function %s() in __first().'%\
  6.                   func.func_name
  7.             if printResult:
  8.                 print func(*args,**kw),'#print in __first().'
  9.             else:
  10.                 return func(*args,**kw)
  11.         return __first
  12.     return _first

  13. >>> def second(printResult=False):
  14.     def _second(func):
  15.         print '%s() was post to _second()'%func.func_name
  16.         def __second(*args,**kw):
  17.             print 'Call the function %s() in __second().'%\
  18.                   func.func_name
  19.             if printResult:
  20.                 print func(*args,**kw),'#print in __second().'
  21.             else:
  22.                 return func(*args,**kw)
  23.         return __second
  24.     return _second

  25. >>> @first(True)
  26. @second(True)
  27. def test():
  28.     return 'hello world'

  29. test() was post to _second()
  30. __second() was post to _first()
  31. >>> test()
  32. Call the function __second() in __first().
  33. Call the function test() in __second().
  34. hello world #print in __second().
  35. None #print in __first().
  36. >>>
復(fù)制代碼
如上,第35行輸出后調(diào)用__second(),而__second()中又調(diào)用了test()并print test(),而后返回__first()中繼續(xù)執(zhí)行print,而這個(gè)print語(yǔ)句print的內(nèi)容是__second()返回的None

它等同于:
  1. >>> def test():
  2.     return 'hello world'

  3. >>> test=second(True)(test)
  4. test() was post to _second()
  5. >>>
  6. >>> test
  7. <function __second at 0x000000000316D2E8>
  8. >>> test=first(True)(test)
  9. __second() was post to _first()
  10. >>> test
  11. <function __first at 0x0000000003344C18>
  12. >>>
復(fù)制代碼
3.多重裝飾器的應(yīng)用:

比如你是項(xiàng)目經(jīng)理,你要求每一個(gè)代碼塊都必須有參數(shù)檢查ArgsType和責(zé)任檢查ResponsibilityRegister,這樣就需要兩個(gè)裝飾器對(duì)此代碼塊進(jìn)行監(jiān)督。
  1. #coding=utf-8
  2. import os,sys,re
  3. from collections import OrderedDict

  4. def ArgsType(*argTypes,**kwTypes):
  5.     u'''ArgsType(*argTypes,**kwTypes)
  6.     options=[('opt_UseTypeOfDefaultValue',False)]

  7.     以下為本函數(shù)相關(guān)的開(kāi)關(guān),并非類(lèi)型檢驗(yàn)相關(guān)的關(guān)鍵字參數(shù),所有options:
  8.     opt_UseTypeOfDefaultValue=>bool:False,為T(mén)rue時(shí),將對(duì)沒(méi)有指定類(lèi)型的帶默
  9.                                認(rèn)值的參數(shù)使用其默認(rèn)值的類(lèi)型
  10.     '''
  11.     def _ArgsType(func):
  12.         #確定所有的parameter name
  13.         argNames=func.func_code.co_varnames[:func.func_code.co_argcount]
  14.         #確定所有的default parameter
  15.         defaults=func.func_defaults
  16.         if defaults:
  17.             defaults=dict(zip(argNames[-len(defaults):],defaults))
  18.         else:defaults=None
  19.         #將“參數(shù)類(lèi)型關(guān)鍵字參數(shù)”中的所有“options關(guān)鍵字參數(shù)”提出
  20.         options=dict()
  21.         for option,default in [('opt_UseTypeOfDefaultValue',False)]:
  22.             options[option]=kwTypes.pop(option,default)
  23.         #argTypes和kwTypes的總長(zhǎng)度應(yīng)該與argNames一致
  24.         if len(argTypes)+len(kwTypes)>len(argNames):
  25.             raise Exception('Too much types to check %s().'%func.func_name)
  26.         #所有kwTypes中的鍵不能覆蓋在argTypes中已經(jīng)占用的names
  27.         if not set(argNames[len(argTypes):]).issuperset(
  28.             set(kwTypes.keys())):
  29.             raise Exception('There is some key in kwTypes '+
  30.                 'which is not in argNames.')
  31.         #確定所有的參數(shù)應(yīng)該有的types
  32.         types=OrderedDict()
  33.         for name in argNames:types[name]=None
  34.         if len(argTypes):
  35.             for i in range(len(argTypes)):
  36.                 name=argNames[i]
  37.                 types[name]=argTypes[i]
  38.         else:
  39.             for name,t in kwTypes.items():
  40.                 types[name]=t
  41.         if len(kwTypes):
  42.             for name,t in kwTypes.items():
  43.                 types[name]=t
  44.         #關(guān)于default parameter的type
  45.         if options['opt_UseTypeOfDefaultValue']:
  46.             for k,v in defaults.items():
  47.                 #如果default parameter的type沒(méi)有另外指定,那么就使用
  48.                 #default parameter的default value的type
  49.                 if types[k]==None:
  50.                     types[k]=type(v)
  51.         def __ArgsType(*args,**kw):
  52.             #order the args
  53.             Args=OrderedDict()
  54.             #init keys
  55.             for name in argNames:Args[name]=None
  56.             #init default values
  57.             if defaults is not None:
  58.                 for k,v in defaults.items():
  59.                     Args[k]=v
  60.             #fill in all args
  61.             for i in range(len(args)):
  62.                 Args[argNames[i]]=args[i]
  63.             #fill in all keyword args
  64.             for k,v in kw.items():
  65.                 Args[k]=v
  66.             #check if there is some None in the values
  67.             if defaults==None:
  68.                 for k in Args:
  69.                     if Args[k]==None:
  70.                         if defaults==None:
  71.                             raise Exception(('%s() needs %r parameter, '+
  72.                                 'which was not given')%(func.func_name,k))
  73.                         else:
  74.                            if not defaults.has_key(k):
  75.                                 raise Exception(('Parameter %r of %s() is'+
  76.                                     ' not a default parameter')%\
  77.                                     (k,func.func_name))
  78.             #check all types
  79.             for k in Args:
  80.                 if not isinstance(Args[k],types[k]):
  81.                     raise TypeError(('Parameter %r of %s() must be '+
  82.                         'a %r object, but you post: %r')%\
  83.                         (k,func.func_name,types[k],Args[k]))
  84.             return func(*args,**kw)
  85.         return __ArgsType
  86.     return _ArgsType

  87. def ResponsibilityRegister(author):
  88.     def _ResponsibilityRegister(func):
  89.         def __ResponsibilityRegister(*args,**kw):
  90.             try:
  91.                 return func(*args,**kw)
  92.             except Exception as e:
  93.                 print ("Something is wrong, It's %s's responsibility."%\
  94.                        author).center(80,'*')
  95.                 raise e
  96.         return __ResponsibilityRegister
  97.     return _ResponsibilityRegister

  98. @ResponsibilityRegister('Kate')
  99. @ArgsType(str,int)
  100. def left(Str,Len=1):
  101.     return Str[:Len]

  102. print 'Good calling:'
  103. print left('hello world',8)
  104. print 'Bad calling:'
  105. print left(3,7)
復(fù)制代碼
這里沒(méi)有文檔,所以調(diào)用者不知道,使用了錯(cuò)誤的調(diào)用,導(dǎo)致出錯(cuò),這是Kate的責(zé)任。

像上面這種,對(duì)代碼有兩種互不相干的檢驗(yàn)時(shí),就可以使用多重裝飾器。

論壇徽章:
26
2015亞冠之胡齊斯坦鋼鐵
日期:2015-06-25 21:40:202015亞冠之柏斯波利斯
日期:2015-08-31 17:03:192015亞冠之柏斯波利斯
日期:2015-11-07 13:10:00程序設(shè)計(jì)版塊每日發(fā)帖之星
日期:2015-11-10 06:20:00每日論壇發(fā)貼之星
日期:2015-11-10 06:20:00程序設(shè)計(jì)版塊每日發(fā)帖之星
日期:2015-11-26 06:20:00程序設(shè)計(jì)版塊每日發(fā)帖之星
日期:2015-12-02 06:20:00黃金圣斗士
日期:2015-12-07 17:57:4615-16賽季CBA聯(lián)賽之天津
日期:2015-12-23 18:34:14程序設(shè)計(jì)版塊每日發(fā)帖之星
日期:2016-01-02 06:20:00程序設(shè)計(jì)版塊每日發(fā)帖之星
日期:2016-01-06 06:20:00每日論壇發(fā)貼之星
日期:2016-01-06 06:20:00
2 [報(bào)告]
發(fā)表于 2015-07-10 17:12 |只看該作者
MARK   
您需要登錄后才可以回帖 登錄 | 注冊(cè)

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號(hào)-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號(hào):11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報(bào)專(zhuān)區(qū)
中國(guó)互聯(lián)網(wǎng)協(xié)會(huì)會(huì)員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過(guò)ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請(qǐng)注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP