国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

Python多重裝飾器

2019-11-14 17:17:43
字體:
來源:轉載
供稿:網友

多重裝飾器,即多個裝飾器修飾同一個對象【實際上并非完全如此,且看下文詳解】

1.裝飾器無參數:

 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  8  9 >>> def second(func):10     print '%s() was post to second()'%func.func_name11     def _second(*args,**kw):12         print 'Call the function %s() in _second().'%func.func_name13         return func(*args,**kw)14     return _second15 16 17 >>> @first18 @second19 def test():return 'hello world'20 21 test() was post to second()22 _second() was post to first()23 >>> test()24 Call the function _second() in _first().25 Call the function test() in _second().26 'hello world'27 >>> 

 

 實際上它是相當于下面的代碼:

 1 >>> def test(): 2     return 'hello world' 3  4 >>> test=second(test) 5 test() was post to second() 6 >>> test 7 <function _second at 0x000000000316D3C8> 8 >>> test=first(test) 9 _second() was post to first()10 >>> test11 <function _first at 0x000000000316D358>12 >>> test()13 Call the function _second() in _first().14 Call the function test() in _second().15 'hello world'16 >>> 

 

 2.裝飾器有參數:

 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 __first12     return _first13 14 >>> def second(printResult=False):15     def _second(func):16         print '%s() was post to _second()'%func.func_name17         def __second(*args,**kw):18             print 'Call the function %s() in __second().'%/19                   func.func_name20             if printResult:21                 print func(*args,**kw),'#print in __second().'22             else:23                 return func(*args,**kw)24         return __second25     return _second26 27 >>> @first(True)28 @second(True)29 def test():30     return 'hello world'31 32 test() was post to _second()33 __second() was post to _first()34 >>> test()35 Call the function __second() in __first().36 Call the function test() in __second().37 hello world #print in __second().38 None #print in __first().39 >>> 

如上,第35行輸出后調用__second(),而__second()中又調用了test()并print test(),而后返回__first()中繼續執行print,而這個print語句print的內容是__second()返回的None

它等同于:

>>> def test():    return 'hello world'>>> test=second(True)(test)test() was post to _second()>>> >>> test<function __second at 0x000000000316D2E8>>>> test=first(True)(test)__second() was post to _first()>>> test<function __first at 0x0000000003344C18>>>> 

3.多重裝飾器的應用:

比如你是項目經理,你要求每一個代碼塊都必須有參數檢查ArgsType和責任檢查ResponsibilityRegister,這樣就需要兩個裝飾器對此代碼塊進行監督。

#coding=utf-8import os,sys,refrom collections import OrderedDictdef ArgsType(*argTypes,**kwTypes):    u'''ArgsType(*argTypes,**kwTypes)    options=[('opt_UseTypeOfDefaultValue',False)]    以下為本函數相關的開關,并非類型檢驗相關的關鍵字參數,所有options:    opt_UseTypeOfDefaultValue=>bool:False,為True時,將對沒有指定類型的帶默                               認值的參數使用其默認值的類型    '''    def _ArgsType(func):        #確定所有的parameter name        argNames=func.func_code.co_varnames[:func.func_code.co_argcount]        #確定所有的default parameter        defaults=func.func_defaults        if defaults:            defaults=dict(zip(argNames[-len(defaults):],defaults))        else:defaults=None        #將“參數類型關鍵字參數”中的所有“options關鍵字參數”提出        options=dict()        for option,default in [('opt_UseTypeOfDefaultValue',False)]:            options[option]=kwTypes.pop(option,default)        #argTypes和kwTypes的總長度應該與argNames一致        if len(argTypes)+len(kwTypes)>len(argNames):            raise Exception('Too much types to check %s().'%func.func_name)        #所有kwTypes中的鍵不能覆蓋在argTypes中已經占用的names        if not set(argNames[len(argTypes):]).issuperset(            set(kwTypes.keys())):            raise Exception('There is some key in kwTypes '+                'which is not in argNames.')        #確定所有的參數應該有的types        types=OrderedDict()        for name in argNames:types[name]=None        if len(argTypes):            for i in range(len(argTypes)):                name=argNames[i]                types[name]=argTypes[i]        else:            for name,t in kwTypes.items():                types[name]=t        if len(kwTypes):            for name,t in kwTypes.items():                types[name]=t        #關于default parameter的type        if options['opt_UseTypeOfDefaultValue']:            for k,v in defaults.items():                #如果default parameter的type沒有另外指定,那么就使用                #default parameter的default value的type                if types[k]==None:                    types[k]=type(v)        def __ArgsType(*args,**kw):            #order the args            Args=OrderedDict()            #init keys            for name in argNames:Args[name]=None            #init default values            if defaults is not None:                for k,v in defaults.items():                    Args[k]=v            #fill in all args            for i in range(len(args)):                Args[argNames[i]]=args[i]            #fill in all keyWord args            for k,v in kw.items():                Args[k]=v            #check if there is some None in the values            if defaults==None:                for k in Args:                    if Args[k]==None:                        if defaults==None:                            raise Exception(('%s() needs %r parameter, '+                                'which was not given')%(func.func_name,k))                        else:                           if not defaults.has_key(k):                                raise Exception(('Parameter %r of %s() is'+                                    ' not a default parameter')%/                                    (k,func.func_name))            #check all types            for k in Args:                if not isinstance(Args[k],types[k]):                    raise TypeError(('Parameter %r of %s() must be '+                        'a %r object, but you post: %r')%/                        (k,func.func_name,types[k],Args[k]))            return func(*args,**kw)        return __ArgsType    return _ArgsTypedef ResponsibilityRegister(author):    def _ResponsibilityRegister(func):        def __ResponsibilityRegister(*args,**kw):            try:                return func(*args,**kw)            except Exception as e:                print ("Something is wrong, It's %s's responsibility."%/                       author).center(80,'*')                raise e        return __ResponsibilityRegister    return _ResponsibilityRegister@ResponsibilityRegister('Kate')@ArgsType(str,int)def left(Str,Len=1):    return Str[:Len]print 'Good calling:'print left('hello world',8)print 'Bad calling:'print left(3,7)

這里沒有文檔,所以調用者不知道,使用了錯誤的調用,導致出錯,這是Kate的責任。

像上面這種,對代碼有兩種互不相干的檢驗時,就可以使用多重裝飾器。

 


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 务川| 榆树市| 嘉定区| 乡城县| 文登市| 县级市| 乌兰浩特市| 蒲江县| 铅山县| 大同市| 祁阳县| 台北市| 凤台县| 若尔盖县| 海兴县| 乐业县| 灵山县| 澎湖县| 武山县| 云阳县| 百色市| 翁牛特旗| 明光市| 灌南县| SHOW| 汾阳市| 凤冈县| 恭城| 塘沽区| 诸暨市| 黔西县| 肇源县| 田阳县| 东乌| 榆林市| 延津县| 安徽省| 永泰县| 游戏| 金阳县| 南和县|