成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久

您的位置:首頁技術文章
文章詳情頁

Python類中的裝飾器在當前類中的聲明與調用詳解

瀏覽:3日期:2022-07-30 08:57:41

我的Python環境:3.7

在Python類里聲明一個裝飾器,并在這個類里調用這個裝飾器。

代碼如下:

class Test(): xx = False def __init__(self): pass def test(func): def wrapper(self, *args, **kwargs): print(self.xx) return func(self, *args, **kwargs) return wrapper @test def test_a(self,a,b): print(f’ok,{a} {b}’)

注意:

1. 其中裝飾器test是在類Test中聲明并在其方法test_a中調用

2. 裝飾器test內層wrapper函數的首參數是self

補充知識:python-類內函數的全局裝飾器

有時,比如寫RF的測試庫的時候,很多方法都寫在一個類里。我們又可能需要一個通用的裝飾器,比如,要給某個底層類的方法打樁,查看入參和出參,用以理解業務;或者要hold住所有的執行錯誤,打印堆棧又不想程序退出或用例直接失敗

比如捕捉錯誤的裝飾器

import tracebackfrom functools import wrapsdef trier(soft=False): ’’’ :param bool soft: 為True時,打印報錯堆棧并忽略異常。默認False,打印報錯堆棧并拋出異常 :return: 如果要給類方法、靜態方法裝飾,則該裝飾器必須處于比@staticmethod裝飾器更內一層才行 ’’’ def realTrier(func): ’’’ :param function func: :return: ’’’ @wraps(func) # 保留__name__ __doc__ __module__ def innerfunc(*args, **kwargs): try:return func(*args, **kwargs) except Exception, e:try: print(traceback.format_exc())except: print eif not soft: raise return innerfunc return realTrier

或者參數跟蹤的裝飾器

def tracer(func): def infunc(*args, **kwargs): print func.__name__, args, kwargs res=infunc(*args, **kwargs) print func.__name__, res return res

這類裝飾器經常會給類里的每個函數都使用

每次都裝飾的話,也挺麻煩

python里可以給類寫個裝飾器,所以可以輸入一個類,返回一個新類,這個新類擁有原來類里的所有方法,但所有方法都被裝飾

使用元類,可以做到這一點。

目前可以批量裝飾普通方法、靜態方法、類方法、屬性,暫不支持__init__和__del__之類的特殊方法,以免出現意外的問題。

目前類B使用了全局裝飾器,假如類B繼承自類A,類C繼承自類B

則類B、類C內的所有方法都被全局裝飾(全局裝飾可以被繼承)

且類B繼承自類A的所有方法也會被全局裝飾

但這種裝飾不會影響到類A,調用類A下的方法時,所有方法都不被裝飾

經過多次嘗試,最后的實現代碼如下

# clswrapper.pydef skipper(func): ’’’ :param function func: :return: ’’’ func.__funskip__=True return funcdef classWrapper(commonDecoratorFunc): def innerMata(inClass): def collect_attrib(key, value, new_attrs): if hasattr(value, ’__funskip__’):new_attrs[key] = valuereturn if hasattr(value, ’__func__’) or isinstance(value, types.FunctionType):if isinstance(value, staticmethod): new_attrs[key] = staticmethod(commonDecoratorFunc(value.__func__)) returnelif isinstance(value, classmethod): new_attrs[key] = classmethod(commonDecoratorFunc(value.__func__)) returnelif not key.startswith(’__’): new_attrs[key] = commonDecoratorFunc(value) return else:if isinstance(value, property): # 當對property類進行重組的時候,我們強制裝飾了property類的fget fset和fdel方法。但是,不是每個propery都有這三個方法,有些是None,強制裝飾會報錯,所以我們這里要考慮提前返回None propertyWrapper = property(fget=commonDecoratorFunc(value.fget) if value.fget else None,fset=commonDecoratorFunc(value.fset) if value.fset else None,fdel=commonDecoratorFunc(value.fdel) if value.fdel else None,doc=value.__doc__) new_attrs[key] = propertyWrapper return new_attrs[key] = value class Meta(type): @classmethod def options(cls, bases, attrs):new_attrs = {}for key, value in attrs.items(): collect_attrib(key, value, new_attrs)for base in bases: for mbase in base.mro(): for key, value in mbase.__dict__.items(): if key not in new_attrs:collect_attrib(key, value, new_attrs)return new_attrs def __new__(cls, name, bases, attrs):new_attrs = cls.options(bases, attrs)return super(Meta, cls).__new__(cls, name, bases, new_attrs) return six.add_metaclass(Meta)(inClass) return innerMata

其中,skipper提供了一個后門,被skipper裝飾的函數會跳過全局裝飾器

使用方法如下

@classWrapper(trier(soft=True))class Tree(object): @skipper def div(self): return 1/0 def divsafe(self): return 1/0t=Tree()print t.divsafe()print t.div()

執行結果如圖

Python類中的裝飾器在當前類中的聲明與調用詳解

一個更完整的示例

from clswrapper那個文件 import skipper, classWrapperimport tracebackfrom functools import wraps’’’為簡潔起見,這次我們用的是不帶參數的trier裝飾器’’’def trier(func): @wraps(func) def inner(*args, **kwargs): try: return func(*args, **kwargs) except: print('EXCEPTION captured at function %s' % func.__name__, file=sys.stderr) print(traceback.format_exc().decode('gbk')) raise return innerif __name__=='__main__': import time class mobj(object): def five(self): w = 1 / 0 class obj(mobj): def __init__(self): # print 'obj.__init__' return @classmethod def one(self): w = 1 / 0 print(’obj.one’) @classWrapper(trier) # 或者用@classWrapper(argTrier(True))替換,則可以不拋出異常 class obj1(obj): aa = 1 def __init__(self): super(obj1, self).__init__() self.var = 1 @classmethod def three(cls): w = 1 / 0 print(’obj1.three’) @staticmethod def four(): w = 1 / 0 print(’obj1.four’) def two(self): w = 1 / 0 print(self.pro) print(’obj1.two’) @property def pro(self): return self.var @pro.setter def pro(self, value): self.var = value / 0 @skipper def eight(self): w=1/0 return w class outerobj(obj1): def seven(self): return 1/0 b = obj1() a = obj1 print(b.var) try: b.two() except: pass try: a.three() except: pass try: a.four() except: pass try: a.one() except: pass try: b.five() except: pass try: b.pro = 3 except: pass print(b.pro) print(a.aa) c=outerobj() try: c.five() except: pass try: c.seven() except: pass try: c.eight() except: print('c.eight被跳過,所以沒有被里層捕獲,才會不打堆棧直接走到這里') print('最后這個會真正觸發異常,因為mobj實例并沒有被裝飾過') m=mobj() time.sleep(1) m.five()

它展示了這個強大裝飾器能處理的各種情況,執行結果應該如下

1EXCEPTION captured at function twoEXCEPTION captured at function threeTraceback (most recent call last):EXCEPTION captured at function four File 'E:/pydev/異常處理裝飾器.py', line 37, in innerEXCEPTION captured at function one return func(*args, **kwargs)EXCEPTION captured at function five File 'E:/pydev/異常處理裝飾器.py', line 138, in two w = 1 / 0ZeroDivisionError: integer division or modulo by zeroTraceback (most recent call last): File 'E:/pydev/異常處理裝飾器.py', line 37, in inner return func(*args, **kwargs) File 'E:/pydev/異常處理裝飾器.py', line 129, in three w = 1 / 0ZeroDivisionError: integer division or modulo by zeroTraceback (most recent call last): File 'E:/pydev/異常處理裝飾器.py', line 37, in inner return func(*args, **kwargs) File 'E:/pydev/異常處理裝飾器.py', line 134, in four w = 1 / 0EXCEPTION captured at function proZeroDivisionError: integer division or modulo by zeroEXCEPTION captured at function fiveTraceback (most recent call last):EXCEPTION captured at function five File 'E:/pydev/異常處理裝飾器.py', line 37, in innerEXCEPTION captured at function seven return func(*args, **kwargs) File 'E:/pydev/異常處理裝飾器.py', line 115, in one w = 1 / 0ZeroDivisionError: integer division or modulo by zeroTraceback (most recent call last): File 'E:/pydev/異常處理裝飾器.py', line 37, in inner return func(*args, **kwargs) File 'E:/pydev/異常處理裝飾器.py', line 104, in five w = 1 / 0ZeroDivisionError: integer division or modulo by zeroTraceback (most recent call last): File 'E:/pydev/異常處理裝飾器.py', line 37, in inner return func(*args, **kwargs) File 'E:/pydev/異常處理裝飾器.py', line 148, in pro self.var = value / 0ZeroDivisionError: integer division or modulo by zero11Traceback (most recent call last): File 'E:/pydev/異常處理裝飾器.py', line 37, in inner return func(*args, **kwargs) File 'E:/pydev/異常處理裝飾器.py', line 104, in five w = 1 / 0ZeroDivisionError: integer division or modulo by zeroTraceback (most recent call last): File 'E:/pydev/異常處理裝飾器.py', line 37, in inner return func(*args, **kwargs) File 'E:/pydev/異常處理裝飾器.py', line 37, in inner return func(*args, **kwargs) File 'E:/pydev/異常處理裝飾器.py', line 104, in five w = 1 / 0ZeroDivisionError: integer division or modulo by zeroTraceback (most recent call last): File 'E:/pydev/異常處理裝飾器.py', line 37, in inner return func(*args, **kwargs) File 'E:/pydev/異常處理裝飾器.py', line 157, in seven return 1/0ZeroDivisionError: integer division or modulo by zeroc.eight被跳過,所以沒有被里層捕獲,才會不打堆棧直接走到這里最后這個會真正觸發異常,因為mobj實例并沒有被裝飾過Traceback (most recent call last): File 'E:/pydev/�쳣����װ����.py', line 212, in <module> m.five() File 'E:/pydev/�쳣����װ����.py', line 104, in five w = 1 / 0ZeroDivisionError: integer division or modulo by zero進程已結束,退出代碼 1

以上這篇Python類中的裝飾器在當前類中的聲明與調用詳解就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持好吧啦網。

標簽: Python 編程
相關文章:
成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久
久久久久久久高潮| 欧美精品粉嫩高潮一区二区| 国产一区二区三区免费不卡 | 春色校园综合激情亚洲| 色8久久人人97超碰香蕉987| 亚洲素人一区二区| 亚洲不卡一区二区三区| 亚洲图色在线| 国产午夜一区二区三区| 成人深夜福利app| 欧美精品乱码久久久久久| 天天亚洲美女在线视频| 亚洲免费中文| 免费亚洲电影在线| 国产91在线观看丝袜| 在线成人小视频| 国产一区二区电影| 欧美精品日韩精品| 国产一区 二区| 美日韩免费视频| 亚洲五月六月丁香激情| 中文亚洲免费| 一级中文字幕一区二区| 永久久久久久| 亚洲三级免费观看| 亚洲第一网站| 亚洲精品乱码久久久久久黑人| 亚洲电影自拍| 成人免费一区二区三区在线观看| 午夜精品婷婷| 国产夜色精品一区二区av| 菠萝蜜视频在线观看一区| 欧美一级午夜免费电影| 成人在线综合网| 久久影院午夜片一区| 欧美在线黄色| 国产精品成人免费在线| 亚洲成人在线| 亚洲一区二区中文在线| 麻豆精品网站| 蜜臀久久久99精品久久久久久| 欧美午夜精品久久久久久孕妇 | 蜜桃精品久久久久久久免费影院| 午夜国产精品影院在线观看| 91久久线看在观草草青青| 韩国午夜理伦三级不卡影院| 欧美一区二区高清| 成人看片黄a免费看在线| 26uuu久久综合| 欧美激情成人在线| 自拍av一区二区三区| 性色av一区二区怡红| 久久99热国产| 精品国产a毛片| 激情亚洲网站| 亚洲r级在线视频| 欧美三区免费完整视频在线观看| 国产精品一区二区在线看| 久久色在线视频| 精品96久久久久久中文字幕无| 一区二区激情视频| 一本大道久久a久久综合婷婷| 久久99热99| 欧美精品一区二区三区蜜臀| 狠久久av成人天堂| 亚洲高清视频在线| 欧美三级午夜理伦三级中视频| 国产成人在线免费| 国产精品色一区二区三区| 亚洲综合社区| 国产精一区二区三区| 国产欧美日韩三区| 噜噜噜噜噜久久久久久91| 国产在线精品视频| 国产精品午夜电影| 麻豆精品网站| 国产白丝精品91爽爽久久| 国产精品理论片| 久久一区亚洲| 不卡一二三区首页| 亚洲自拍另类综合| 欧美精品tushy高清| 国产精品分类| 日本午夜一本久久久综合| 精品国产伦一区二区三区观看方式 | 久久久久国产精品厨房| 一区二区三区四区五区在线| 国内偷窥港台综合视频在线播放| 欧美国产一区二区| 久久亚洲欧美| 91在线你懂得| 性欧美疯狂xxxxbbbb| 欧美岛国在线观看| 一区二区黄色| 国产精品99久| 亚洲欧美另类久久久精品| 欧美日韩国产在线播放网站| 欧美日韩国产一区精品一区| 蜜桃精品视频在线| 久久精品欧美一区二区三区麻豆| 一本久道久久综合中文字幕| 91香蕉视频黄| 日韩精品成人一区二区在线| www成人在线观看| 香港久久久电影| 不卡电影一区二区三区| 天天操天天色综合| 国产欧美视频在线观看| 在线亚洲精品福利网址导航| 合欧美一区二区三区| 精品一区二区影视| 成人欧美一区二区三区白人| 欧美一级日韩免费不卡| 国产伦精品一区二区三区四区免费 | 蜜桃传媒麻豆第一区在线观看| 国产亚洲制服色| 欧美视频在线观看一区| 99re热精品| 91在线观看视频| 九色综合狠狠综合久久| 一区二区在线观看视频| 久久嫩草精品久久久精品一| 成人av在线观| 亚洲成人av免费| 久久精品亚洲精品国产欧美kt∨| 欧美亚洲一区二区在线| 999在线观看精品免费不卡网站| 成人综合婷婷国产精品久久蜜臀| 爽好多水快深点欧美视频| 国产精品国产三级国产a | 国产欧美短视频| 午夜免费电影一区在线观看| 国产一区二区三区电影在线观看| 亚洲一区二区三区视频在线播放 | 老牛嫩草一区二区三区日本| 欧美日韩国产在线一区| 懂色av中文字幕一区二区三区| 天堂久久久久va久久久久| 国产精品国产三级国产aⅴ入口| 欧美精品一区二区三区蜜桃 | 影音先锋日韩资源| 欧美在线三区| 国产成人午夜高潮毛片| 蜜乳av一区二区三区| 国产精品福利影院| 精品久久人人做人人爽| 欧美日韩不卡一区| 美日韩精品视频| 在线一区亚洲| 国产一区免费视频| a在线欧美一区| 国产精品中文字幕一区二区三区| 日韩中文字幕区一区有砖一区 | 亚洲一区二区影院| 亚洲日本在线视频观看| 久久精品视频一区二区三区| 91麻豆精品国产自产在线观看一区 | 亚洲女人av| 亚洲精品在线视频观看| 黄色精品一区| 91麻豆高清视频| 99精品欧美一区二区三区小说 | 色爱区综合激月婷婷| 亚洲一区欧美二区| 亚洲午夜视频| 欧美视频亚洲视频| 色综合色综合色综合| 国产欧美欧美| 一区在线播放| 亚洲高清成人| 一区精品久久| 好看的日韩av电影| 伊甸园精品99久久久久久| 欧美日韩天堂| 欧美日韩成人| 国产一区自拍视频| 欧美视频不卡| 狠狠色综合网站久久久久久久| 欧美日韩综合另类| 欧美福利在线| 欧美成人综合| 国产精品红桃| 狠久久av成人天堂| 99成人在线| 亚洲免费不卡| 国产欧美精品久久| 国产精品日韩精品欧美精品| 一区二区三区四区五区精品视频| 国产亚洲欧美一区二区| 亚洲在线国产日韩欧美| 国产精品日韩精品欧美精品| 另类天堂av| 欧美性大战xxxxx久久久| 欧美性猛片aaaaaaa做受| 欧美日韩亚洲综合一区| 777久久久精品| 欧美成人官网二区| 2017欧美狠狠色| 国产精品久久久久影院色老大| 国产精品久久久久久久久免费樱桃|