电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

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

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

瀏覽:5日期: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 編程
相關文章:
主站蜘蛛池模板: 塑料托盘厂家直销-吹塑托盘生产厂家-力库塑业【官网】 | 江苏皓越真空设备有限公司 | 无线讲解器-导游讲解器-自助讲解器-分区讲解系统 品牌生产厂家[鹰米讲解-合肥市徽马信息科技有限公司] | 等离子表面处理机-等离子表面活化机-真空等离子清洗机-深圳市东信高科自动化设备有限公司 | 上海皓越真空设备有限公司官网-真空炉-真空热压烧结炉-sps放电等离子烧结炉 | 口臭的治疗方法,口臭怎么办,怎么除口臭,口臭的原因-口臭治疗网 | 闸阀_截止阀_止回阀「生产厂家」-上海卡比阀门有限公司 | 东莞市海宝机械有限公司-不锈钢分选机-硅胶橡胶-生活垃圾-涡电流-静电-金属-矿石分选机 | 智能垃圾箱|垃圾房|垃圾分类亭|垃圾分类箱专业生产厂家定做-宿迁市传宇环保设备有限公司 | 上海logo设计| 语料库-提供经典范文,文案句子,常用文书,您的写作得力助手 | 电伴热系统施工_仪表电伴热保温箱厂家_沃安电伴热管缆工业技术(济南)有限公司 | 合肥网带炉_安徽箱式炉_钟罩炉-合肥品炙装备科技有限公司 | 根系分析仪,大米外观品质检测仪,考种仪,藻类鉴定计数仪,叶面积仪,菌落计数仪,抑菌圈测量仪,抗生素效价测定仪,植物表型仪,冠层分析仪-杭州万深检测仪器网 | 运动木地板厂家_体育木地板安装_篮球木地板选购_实木运动地板价格 | 恒温油槽-恒温水槽-低温恒温槽厂家-宁波科麦仪器有限公司 | 阻垢剂-反渗透缓蚀阻垢剂厂家-山东鲁东环保科技有限公司 | 济南玻璃安装_济南玻璃门_济南感应门_济南玻璃隔断_济南玻璃门维修_济南镜片安装_济南肯德基门_济南高隔间-济南凯轩鹏宇玻璃有限公司 | 山东氧化铁红,山东铁红-淄博科瑞化工有限公司| EDLC超级法拉电容器_LIC锂离子超级电容_超级电容模组_软包单体电容电池_轴向薄膜电力电容器_深圳佳名兴电容有限公司_JMX专注中高端品牌电容生产厂家 | 中控室大屏幕-上海亿基自动化控制系统工程有限公司 | 阿尔法-MDR2000无转子硫化仪-STM566 SATRA拉力试验机-青岛阿尔法仪器有限公司 | 知网论文检测系统入口_论文查重免费查重_中国知网论文查询_学术不端检测系统 | 合肥卓创建筑装饰,专业办公室装饰、商业空间装修与设计。 | CE认证_FCC认证_CCC认证_MFI认证_UN38.3认证-微测检测 CNAS实验室 | 淬火设备-钎焊机-熔炼炉-中频炉-锻造炉-感应加热电源-退火机-热处理设备-优造节能 | (中山|佛山|江门)环氧地坪漆,停车场地板漆,车库地板漆,聚氨酯地板漆-中山永旺地坪漆厂家 | 活性炭-果壳木质煤质柱状粉状蜂窝活性炭厂家价格多少钱 | 涂层测厚仪_漆膜仪_光学透过率仪_十大创新厂家-果欧电子科技公司 | 上海诺狮景观规划设计有限公司 | 土壤有机碳消解器-石油|表层油类分析采水器-青岛溯源环保设备有限公司 | 单螺旋速冻机-双螺旋-流态化-隧道式-食品速冻机厂家-广州冰泉制冷 | sfp光模块,高速万兆光模块工厂-性价比更高的光纤模块制造商-武汉恒泰通 | 二维运动混料机,加热型混料机,干粉混料机-南京腾阳干燥设备厂 | 氢氧化钾厂家直销批发-济南金昊化工有限公司 | 磁力轮,磁力联轴器,磁齿轮,钕铁硼磁铁-北京磁运达厂家 | 鹤壁创新仪器公司-全自动量热仪,定硫仪,煤炭测硫仪,灰熔点测定仪,快速自动测氢仪,工业分析仪,煤质化验仪器 | 快速门厂家批发_PVC快速卷帘门_高速门_高速卷帘门-广州万盛门业 快干水泥|桥梁伸缩缝止水胶|伸缩缝装置生产厂家-广东广航交通科技有限公司 | 一体化净水器_一体化净水设备_一体化水处理设备-江苏旭浩鑫环保科技有限公司 | 派克防爆伺服电机品牌|国产防爆伺服电机|高低温伺服电机|杭州摩森机电科技有限公司 | 闭端端子|弹簧螺式接线头|防水接线头|插线式接线头|端子台|电源线扣+护线套|印刷电路板型端子台|金笔电子代理商-上海拓胜电气有限公司 |