>>deffirst(func):print'%s()wasposttofirst()'%func.func_namedef_first(*args,**kw):print'Callthefunction%s()in_first().'%func.func_namereturnfunc(*args,**kw)return_first>>>defs" />

亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

Python中的多重裝飾器

系統 1790 0

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

1.裝飾器無參數:

復制代碼 代碼如下:

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

>>> test=first(test)
_second() was post to first()
>>> test

>>> test()
Call the function _second() in _first().
Call the function test() in _second().
'hello world'
>>>


2.裝飾器有參數:
復制代碼 代碼如下:

>>> 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行輸出后調用__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

>>> test=first(True)(test)
__second() was post to _first()
>>> test

>>>


3.多重裝飾器的應用:

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

復制代碼 代碼如下:

#coding=utf-8
import os,sys,re
from collections import OrderedDict

def 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 _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)

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

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


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 在线播放日韩 | 欧美成人xx免费视频 | 欧美精品v欧洲高清 | 成人中文字幕一区二区三区 | 欧美激情aa毛片 | 中文字幕亚洲一区二区va在线 | 婷婷综合五月中文字幕欧美 | 免费观看国产精品 | 日本欧洲95视频 | 视频在线观看91 | 免费一级欧美片在线观看 | 成人a视频片在线观看免费 成人a视频在线观看 | 亚洲羞羞视频 | 最新日韩在线观看 | 免费特黄级夫费生活片 | 欧美日韩国产一区二区三区播放 | 国产成人精品999在线 | 亚洲福利视频精选在线视频 | 国产精品成人69xxx免费视频 | 婷婷五月情 | 男人的天堂黄 | 国内精品伊人久久久影院 | 草莓视频一区二区精品 | 日本爱爱片 | 伊人色综合久久天天网 | 国产精品国产精品国产专区不卡 | 黑人边吃奶边扎下面激情视频 | 精品小视频在线 | 99久久国产综合精品麻豆 | 美女国产 | 一本伊大人香蕉久久网手机 | 久久香蕉影视 | 激情浪荡yin乱之合集 | 99精品国产一区二区三区 | 国产一二精品 | 日日夜夜免费精品视频 | 国内视频一区二区 | xxxx成年视频免费 | 国产一级一级一级成人毛片 | 欧美日韩午夜视频 | 久久精品re |