国产成人精品久久免费动漫-国产成人精品天堂-国产成人精品区在线观看-国产成人精品日本-a级毛片无码免费真人-a级毛片毛片免费观看久潮喷

您的位置:首頁技術(shù)文章
文章詳情頁

Python類中的裝飾器在當(dāng)前類中的聲明與調(diào)用詳解

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

我的Python環(huán)境:3.7

在Python類里聲明一個(gè)裝飾器,并在這個(gè)類里調(diào)用這個(gè)裝飾器。

代碼如下:

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} ’)

注意:

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

2. 裝飾器test內(nèi)層wrapper函數(shù)的首參數(shù)是self

補(bǔ)充知識(shí):python-類內(nèi)函數(shù)的全局裝飾器

有時(shí),比如寫RF的測試庫的時(shí)候,很多方法都寫在一個(gè)類里。我們又可能需要一個(gè)通用的裝飾器,比如,要給某個(gè)底層類的方法打樁,查看入?yún)⒑统鰠?,用以理解業(yè)務(wù);或者要hold住所有的執(zhí)行錯(cuò)誤,打印堆棧又不想程序退出或用例直接失敗

比如捕捉錯(cuò)誤的裝飾器

import tracebackfrom functools import wrapsdef trier(soft=False): ’’’ :param bool soft: 為True時(shí),打印報(bào)錯(cuò)堆棧并忽略異常。默認(rèn)False,打印報(bào)錯(cuò)堆棧并拋出異常 :return: 如果要給類方法、靜態(tài)方法裝飾,則該裝飾器必須處于比@staticmethod裝飾器更內(nèi)一層才行 ’’’ 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

或者參數(shù)跟蹤的裝飾器

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

這類裝飾器經(jīng)常會(huì)給類里的每個(gè)函數(shù)都使用

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

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

使用元類,可以做到這一點(diǎn)。

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

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

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

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

但這種裝飾不會(huì)影響到類A,調(diào)用類A下的方法時(shí),所有方法都不被裝飾

經(jīng)過多次嘗試,最后的實(shí)現(xiàn)代碼如下

# 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): # 當(dāng)對property類進(jìn)行重組的時(shí)候,我們強(qiáng)制裝飾了property類的fget fset和fdel方法。但是,不是每個(gè)propery都有這三個(gè)方法,有些是None,強(qiáng)制裝飾會(huì)報(bào)錯(cuò),所以我們這里要考慮提前返回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提供了一個(gè)后門,被skipper裝飾的函數(shù)會(huì)跳過全局裝飾器

使用方法如下

@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()

執(zhí)行結(jié)果如圖

Python類中的裝飾器在當(dāng)前類中的聲明與調(diào)用詳解

一個(gè)更完整的示例

from clswrapper那個(gè)文件 import skipper, classWrapperimport tracebackfrom functools import wraps’’’為簡潔起見,這次我們用的是不帶參數(shù)的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被跳過,所以沒有被里層捕獲,才會(huì)不打堆棧直接走到這里') print('最后這個(gè)會(huì)真正觸發(fā)異常,因?yàn)閙obj實(shí)例并沒有被裝飾過') m=mobj() time.sleep(1) m.five()

它展示了這個(gè)強(qiáng)大裝飾器能處理的各種情況,執(zhí)行結(jié)果應(yīng)該如下

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被跳過,所以沒有被里層捕獲,才會(huì)不打堆棧直接走到這里最后這個(gè)會(huì)真正觸發(fā)異常,因?yàn)閙obj實(shí)例并沒有被裝飾過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進(jìn)程已結(jié)束,退出代碼 1

以上這篇Python類中的裝飾器在當(dāng)前類中的聲明與調(diào)用詳解就是小編分享給大家的全部內(nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持好吧啦網(wǎng)。

標(biāo)簽: Python 編程
相關(guān)文章:
主站蜘蛛池模板: 亚洲精品一二三 | m男亚洲一区中文字幕 | 日本在线视频观看 | 欧美成人三级视频 | 亚洲 自拍 另类 欧美 综合 | 久久精品成人一区二区三区 | 国产亚洲精品久久久久久 | 泷泽萝拉亚洲精品中文字幕 | 高清欧美日本视频免费观看 | 18年大片免费在线观看 | 国产亚洲高清视频 | 香蕉视频老司机 | xh98hx国产免费| 欧美日本一区二区三区道 | 国产自一区 | 女人让男人桶的小视频 | 日本成aⅴ人片日本伦 | 日韩亚洲人成网站在线播放 | 亚洲精品一区二区中文 | 永久免费不卡在线观看黄网站 | 成年美女黄网站色视频大全免费 | 久久久久9999 | 热99re久久精品精品免费 | 97在线免费观看视频 | 欧美另类在线观看 | 亚洲看黄| 国内国语一级毛片在线视频 | 国产午夜精品久久久久小说 | 亚洲成年人网址 | 成人欧美网站 | 一级日韩 | 国产成人精品一区二区秒拍 | 大片毛片 | 成年人毛片 | 中国女人18xnxx视频 | 欧美精品在线视频 | 欧美日韩一区二区三区在线播放 | 亚洲色欧美 | 亚洲视频免费在线 | 在线成人免费视频 | 欧美色操|