最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python中的多重裝飾器

 更新時(shí)間:2015年04月11日 10:49:27   投稿:junjie  
這篇文章主要介紹了Python中的多重裝飾器,多重裝飾器即多個(gè)裝飾器修飾同一個(gè)對(duì)象,但實(shí)際上并非完全如此,本文用實(shí)例講解了各種情況,需要的朋友可以參考下

多重裝飾器,即多個(gè)裝飾器修飾同一個(gè)對(duì)象【實(shí)際上并非完全如此,且看下文詳解】

1.裝飾器無(wú)參數(shù):

復(fù)制代碼 代碼如下:

>>> 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'
>>>

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

復(fù)制代碼 代碼如下:

>>> 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ù):
復(fù)制代碼 代碼如下:

>>> 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,而這個(gè)print語(yǔ)句print的內(nèi)容是__second()返回的None

它等同于:

復(fù)制代碼 代碼如下:

>>> 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)用:

比如你是項(xiàng)目經(jīng)理,你要求每一個(gè)代碼塊都必須有參數(shù)檢查ArgsType和責(zé)任檢查ResponsibilityRegister,這樣就需要兩個(gè)裝飾器對(duì)此代碼塊進(jìn)行監(jiān)督。

復(fù)制代碼 代碼如下:

#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),并非類型檢驗(yàn)相關(guān)的關(guān)鍵字參數(shù),所有options:
    opt_UseTypeOfDefaultValue=>bool:False,為True時(shí),將對(duì)沒有指定類型的帶默
                               認(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的總長(zhǎng)度應(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)用者不知道,使用了錯(cuò)誤的調(diào)用,導(dǎo)致出錯(cuò),這是Kate的責(zé)任。

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

相關(guān)文章

  • 自制python包并通過pip上傳pypi

    自制python包并通過pip上傳pypi

    這篇文章主要為大家介紹了自己制作python包并通過pip上傳pypi實(shí)現(xiàn)過程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-09-09
  • Numpy廣播域的理解

    Numpy廣播域的理解

    本文主要介紹了Numpy廣播域的理解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-03-03
  • python之pandas用法大全

    python之pandas用法大全

    本文講解了python的pandas基本用法,大家可以參考下
    2018-03-03
  • Python中eval帶來(lái)的潛在風(fēng)險(xiǎn)代碼分析

    Python中eval帶來(lái)的潛在風(fēng)險(xiǎn)代碼分析

    這篇文章主要介紹了Python中eval帶來(lái)的潛在風(fēng)險(xiǎn)代碼分析,具有一定借鑒價(jià)值,需要的朋友可以參考下。
    2017-12-12
  • python 判斷一個(gè)進(jìn)程是否存在

    python 判斷一個(gè)進(jìn)程是否存在

    判斷python判斷一個(gè)進(jìn)程是否存在
    2009-04-04
  • python+Matplotlib?繪制帶置信區(qū)間的折線圖

    python+Matplotlib?繪制帶置信區(qū)間的折線圖

    這篇文章主要介紹了python繪制帶置信區(qū)間的折線圖,在本文中,我們將使用?numpy?模塊生成隨機(jī)數(shù)據(jù),并使用?matplotlib?庫(kù)實(shí)現(xiàn)數(shù)據(jù)可視化,需要的朋友可以參考下
    2023-05-05
  • python 對(duì)txt中每行內(nèi)容進(jìn)行批量替換的方法

    python 對(duì)txt中每行內(nèi)容進(jìn)行批量替換的方法

    今天小編就為大家分享一篇python 對(duì)txt中每行內(nèi)容進(jìn)行批量替換的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來(lái)看看吧
    2018-07-07
  • 解決hive中導(dǎo)入text文件遇到的坑

    解決hive中導(dǎo)入text文件遇到的坑

    這篇文章主要介紹了解決hive中導(dǎo)入text文件遇到的坑,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來(lái)看看吧
    2021-04-04
  • Python實(shí)現(xiàn)PDF轉(zhuǎn)Word的方法詳解

    Python實(shí)現(xiàn)PDF轉(zhuǎn)Word的方法詳解

    由于PDF的文件大多都是只讀文件,有時(shí)候?yàn)榱藵M足可以編輯的需要通常可以將PDF文件直接轉(zhuǎn)換成Word文件進(jìn)行操作。本文為大家整理了一些實(shí)現(xiàn)方法,希望對(duì)大家有所幫助
    2023-02-02
  • 妙用itchat! python實(shí)現(xiàn)久坐提醒功能

    妙用itchat! python實(shí)現(xiàn)久坐提醒功能

    python編寫的久坐提醒,給最愛的那個(gè)她,這篇文章主要為大家分享了python久坐提醒功能的實(shí)現(xiàn)代碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-11-11

最新評(píng)論

许昌市| 开远市| 新蔡县| 郓城县| 日照市| 杂多县| 当雄县| 永昌县| 收藏| 松桃| 丹寨县| 正宁县| 营口市| 唐河县| 上蔡县| 义乌市| 蓬莱市| 揭西县| 泸水县| 潮安县| 青冈县| 杭锦后旗| 百色市| 泗阳县| 依兰县| 永寿县| 宣汉县| 延寿县| 纳雍县| 广平县| 荣成市| 新闻| 漳平市| 晋城| 瑞昌市| 馆陶县| 梅河口市| 长顺县| 武威市| 敦化市| 德安县|