午夜国产狂喷潮在线观看|国产AⅤ精品一区二区久久|中文字幕AV中文字幕|国产看片高清在线

    Python中的多重裝飾器
    來源:易賢網(wǎng) 閱讀:1507 次 日期:2015-04-14 15:27:45
    溫馨提示:易賢網(wǎng)小編為您整理了“Python中的多重裝飾器”,方便廣大網(wǎng)友查閱!

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

    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'

    >>>

    實際上它是相當(dāng)于下面的代碼:

    代碼如下:

    >>> 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.多重裝飾器的應(yīng)用:

    比如你是項目經(jīng)理,你要求每一個代碼塊都必須有參數(shù)檢查ArgsType和責(zé)任檢查ResponsibilityRegister,這樣就需要兩個裝飾器對此代碼塊進(jìn)行監(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時,將對沒有指定類型的帶默

    認(rèn)值的參數(shù)使用其默認(rèn)值的類型

    '''

    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的總長度應(yīng)該與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ù)應(yīng)該有的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)用,導(dǎo)致出錯,這是Kate的責(zé)任。

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

    更多信息請查看IT技術(shù)專欄

    更多信息請查看腳本欄目
    易賢網(wǎng)手機(jī)網(wǎng)站地址:Python中的多重裝飾器
    由于各方面情況的不斷調(diào)整與變化,易賢網(wǎng)提供的所有考試信息和咨詢回復(fù)僅供參考,敬請考生以權(quán)威部門公布的正式信息和咨詢?yōu)闇?zhǔn)!

    2025國考·省考課程試聽報名

    • 報班類型
    • 姓名
    • 手機(jī)號
    • 驗證碼
    關(guān)于我們 | 聯(lián)系我們 | 人才招聘 | 網(wǎng)站聲明 | 網(wǎng)站幫助 | 非正式的簡要咨詢 | 簡要咨詢須知 | 新媒體/短視頻平臺 | 手機(jī)站點 | 投訴建議
    工業(yè)和信息化部備案號:滇ICP備2023014141號-1 云南省教育廳備案號:云教ICP備0901021 滇公網(wǎng)安備53010202001879號 人力資源服務(wù)許可證:(云)人服證字(2023)第0102001523號
    云南網(wǎng)警備案專用圖標(biāo)
    聯(lián)系電話:0871-65099533/13759567129 獲取招聘考試信息及咨詢關(guān)注公眾號:hfpxwx
    咨詢QQ:1093837350(9:00—18:00)版權(quán)所有:易賢網(wǎng)
    云南網(wǎng)警報警專用圖標(biāo)