亚洲免费乱码视频,日韩 欧美 国产 动漫 一区,97在线观看免费视频播国产,中文字幕亚洲图片

      1. <legend id="ppnor"></legend>

      2. 
        
        <sup id="ppnor"><input id="ppnor"></input></sup>
        <s id="ppnor"></s>

        Python中的多重裝飾器

        字號:


            多重裝飾器,即多個裝飾器修飾同一個對象【實際上并非完全如此,且看下文詳解】
            1.裝飾器無參數(shù):
            代碼如下:
            >>> def first(func):
            print '%s() was post to first()'%func.func_name
            def _first(*args,**kw):
            print 'Call the function %s() in _first().'%func.func_name
            return func(*args,**kw)
            return _first
            >>> def second(func):
            print '%s() was post to second()'%func.func_name
            def _second(*args,**kw):
            print 'Call the function %s() in _second().'%func.func_name
            return func(*args,**kw)
            return _second
            >>> @first
            @second
            def test():return 'hello world'
            test() was post to second()
            _second() was post to first()
            >>> test()
            Call the function _second() in _first().
            Call the function test() in _second().
            'hello world'
            >>>
            實際上它是相當于下面的代碼:
            代碼如下:
            >>> def test():
            return 'hello world'
            >>> test=second(test)
            test() was post to second()
            >>> test
            <function _second at 0x000000000316D3C8>
            >>> test=first(test)
            _second() was post to first()
            >>> test
            <function _first at 0x000000000316D358>
            >>> test()
            Call the function _second() in _first().
            Call the function test() in _second().
            'hello world'
            >>>
            2.裝飾器有參數(shù):
            代碼如下:
            >>> def first(printResult=False):
            def _first(func):
            print '%s() was post to _first()'%func.func_name
            def __first(*args,**kw):
            print 'Call the function %s() in __first().'%\
            func.func_name
            if printResult:
            print func(*args,**kw),'#print in __first().'
            else:
            return func(*args,**kw)
            return __first
            return _first
            >>> def second(printResult=False):
            def _second(func):
            print '%s() was post to _second()'%func.func_name
            def __second(*args,**kw):
            print 'Call the function %s() in __second().'%\
            func.func_name
            if printResult:
            print func(*args,**kw),'#print in __second().'
            else:
            return func(*args,**kw)
            return __second
            return _second
            >>> @first(True)
            @second(True)
            def test():
            return 'hello world'
            test() was post to _second()
            __second() was post to _first()
            >>> test()
            Call the function __second() in __first().
            Call the function test() in __second().
            hello world #print in __second().
            None #print in __first().
            >>>
            如上,第35行輸出后調(diào)用__second(),而__second()中又調(diào)用了test()并print test(),而后返回__first()中繼續(xù)執(zhí)行print,而這個print語句print的內(nèi)容是__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.多重裝飾器的應用:
            比如你是項目經(jīng)理,你要求每一個代碼塊都必須有參數(shù)檢查ArgsType和責任檢查ResponsibilityRegister,這樣就需要兩個裝飾器對此代碼塊進行監(jiān)督。
            代碼如下:
            #coding=utf-8
            import os,sys,re
            from collections import OrderedDict
            def ArgsType(*argTypes,**kwTypes):
            u'''ArgsType(*argTypes,**kwTypes)
            options=[('opt_UseTypeOfDefaultValue',False)]
            以下為本函數(shù)相關(guān)的開關(guān),并非類型檢驗相關(guān)的關(guān)鍵字參數(shù),所有options:
            opt_UseTypeOfDefaultValue=>bool:False,為True時,將對沒有指定類型的帶默
            認值的參數(shù)使用其默認值的類型
            '''
            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
            #將“參數(shù)類型關(guān)鍵字參數(shù)”中的所有“options關(guān)鍵字參數(shù)”提出
            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中已經(jīng)占用的names
            if not set(argNames[len(argTypes):]).issuperset(
            set(kwTypes.keys())):
            raise Exception('There is some key in kwTypes '+
            'which is not in argNames.')
            #確定所有的參數(shù)應該有的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
            #關(guān)于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 _ArgsType
            def 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)
            這里沒有文檔,所以調(diào)用者不知道,使用了錯誤的調(diào)用,導致出錯,這是Kate的責任。
            像上面這種,對代碼有兩種互不相干的檢驗時,就可以使用多重裝飾器。