欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python裝飾器重載內(nèi)置的使用

 更新時(shí)間:2024年01月16日 09:46:14   作者:梯閱線條  
本文主要介紹了Python裝飾器重載內(nèi)置的使用,詳細(xì)介紹如何創(chuàng)建裝飾器,如何使用裝飾器來重載內(nèi)置函數(shù),具有一定的參考價(jià)值,感興趣的可以了解一下

python2.x的新式類和python3.x的全部類,內(nèi)置操作表達(dá)式調(diào)用,不會觸發(fā)__getattr__()和__getattribute__()。參考《python的getattr和getattribute攔截內(nèi)置操作》。

NO內(nèi)置操作表達(dá)式(隱式調(diào)用)對應(yīng)方法(顯式調(diào)用)
1索引操作[i]__getitem__
2加法(連接)操作+__coerce__ __add__
3括號調(diào)用()__call__
4打印print()__str__

__coerce__:表示強(qiáng)制類型轉(zhuǎn)換,使用加法(或連接)操作+時(shí),不同類型會觸發(fā)類型轉(zhuǎn)換或者報(bào)錯(cuò)。

內(nèi)置操作調(diào)用方式:隱式調(diào)用,即調(diào)用表達(dá)式;顯式調(diào)用,即調(diào)用方法名。

1.1 Py3內(nèi)置操作表達(dá)式調(diào)用無法委托

描述

內(nèi)置操作的表達(dá)式調(diào)用,無法在python3.0下委托,因?yàn)椴粫|發(fā)__getattr__()和__getattribute__()。

示例

>>> def traceCall(*args):#跟蹤調(diào)用
    if trace:
        print('['+','.join(map(str,args))+']')

        
>>> def accessCtrl(forbid):
    def onDecorator(aCls):
        class onInstance:
            def __init__(self,*args,**kargs):
                self.__wrapped=aCls(*args,**kargs)
            def __getattr__(self,attr):
                traceCall('getattr',attr)
                if forbid(attr):
                    raise TypeError('禁止訪問:'+attr)
                else:
                    return getattr(self.__wrapped,attr)
            def __setattr__(self,attr,value):
                traceCall('setattr',attr,value)
                # 壓縮后的變量名為 _onInstance__wrapped
                if attr=='_onInstance__wrapped':
                    self.__dict__[attr]=value
                elif forbid(attr):
                    raise TypeError('禁止設(shè)置:'+attr)
                else:
                    setattr(self.__wrapped,attr,value)
        return onInstance
    return onDecorator

>>> def privateAttr(*privates):
    return accessCtrl(forbid=(lambda attr:attr in privates))

>>> @privateAttr('phone')
class Staff_Private:
    def __init__(self,name,phone):
        self.name=name
        self.phone=phone
    def __str__(self):
        return 'Staff_Private->手機(jī)號:'+str(self.phone)
    def __add__(self,num):
        self.phone+=num

Python2.x執(zhí)行

Py2的__getattr__()攔截print()和+等內(nèi)置操作的表達(dá)式調(diào)用,正確的委托給裝飾對象。

#python2.x執(zhí)行
>>> trace=True
>>> sp1=Staff_Private('梯閱線條',110)
[setattr,_onInstance__wrapped,Staff_Private->手機(jī)號:110]
#py2傳統(tǒng)類 攔截內(nèi)置操作表達(dá)式調(diào)用-隱式調(diào)用,print()
>>> print(sp1)
[getattr,__str__]
Staff_Private->手機(jī)號:110
#py2傳統(tǒng)類 攔截內(nèi)置操作表達(dá)式調(diào)用-隱式調(diào)用,+
>>> sp1+1
[getattr,__coerce__]
[getattr,__add__]
>>> print(sp1)
[getattr,__str__]
Staff_Private->手機(jī)號:111

Python3.x執(zhí)行

Py3的__getattr__()不攔截print()和+等內(nèi)置操作的表達(dá)式調(diào)用,無法委托給裝飾對象。

#python3.x執(zhí)行
>>> trace=True
>>> sp1=Staff_Private('梯閱線條',110)
[setattr,_onInstance__wrapped,Staff_Private->手機(jī)號:110]
#py3沒有攔截內(nèi)置操作 print
>>> print(sp1)
<__main__.accessCtrl.<locals>.onDecorator.<locals>.onInstance object at 0x0000019736C2F4F0>
#py3沒有攔截內(nèi)置操作 + 
>>> sp1+1
Traceback (most recent call last):
  File "<pyshell#11>", line 1, in <module>
    sp1+1
TypeError: unsupported operand type(s) for +: 'onInstance' and 'int'

1.2 裝飾器重載內(nèi)置操作

描述

Python3.x的裝飾器重載內(nèi)置操作運(yùn)算符方法,來攔截裝飾類對應(yīng)的內(nèi)置表達(dá)式調(diào)用。

比如,重載__str__()攔截print(),__add__()攔截+。

示例

>>> def traceCall(*args):#跟蹤調(diào)用
    if trace:
        print('['+','.join(map(str,args))+']')
>>> def accessCtrl(forbid):
    def onDecorator(aCls):
        class onInstance:
            def __init__(self,*args,**kargs):
                self.__wrapped=aCls(*args,**kargs)
            def __getattr__(self,attr):
                traceCall('getattr',attr)
                if forbid(attr):
                    raise TypeError('禁止訪問:'+attr)
                else:
                    return getattr(self.__wrapped,attr)
            def __setattr__(self,attr,value):
                traceCall('setattr',attr,value)
                # 壓縮后的變量名為 _onInstance__wrapped
                if attr=='_onInstance__wrapped':
                    self.__dict__[attr]=value
                elif forbid(attr):
                    raise TypeError('禁止設(shè)置:'+attr)
                else:
                    setattr(self.__wrapped,attr,value)
            # print()觸發(fā)__str__()
            def __str__(self):
                traceCall('onInstance,__str__')
                # str()觸發(fā)__str__()
                return str(self.__wrapped)
            # + 觸發(fā) __add__()    
            def __add__(self,other):
                traceCall('onInstance,__add__',other)
                return self.__wrapped+other
        return onInstance
    return onDecorator

>>> def privateAttr(*privates):
    return accessCtrl(forbid=(lambda attr:attr in privates))

>>> @privateAttr('phone')
class Staff_Private:
    def __init__(self,name,phone):
        self.name=name
        self.phone=phone
    def __str__(self):
        traceCall('Staff_Private,__str__')
        return 'Staff_Private->手機(jī)號:'+str(self.phone)
    def __add__(self,num):
        traceCall('Staff_Private,__add__',num)
        self.phone+=num

        
>>> trace=True
>>> sp1=Staff_Private('梯閱線條',110)
[Staff_Private,__str__]#traceCall調(diào)用print()觸發(fā)__str__()
[setattr,_onInstance__wrapped,Staff_Private->手機(jī)號:110]
# print()觸發(fā)__str__()
>>> print(sp1)
[onInstance,__str__]
[Staff_Private,__str__]
Staff_Private->手機(jī)號:110
# + 觸發(fā) __add__()
>>> sp1+1
[onInstance,__add__,1]
[Staff_Private,__add__,1]
>>> print(sp1)
[onInstance,__str__]
[Staff_Private,__str__]
Staff_Private->手機(jī)號:111

到此這篇關(guān)于Python裝飾器重載內(nèi)置的使用的文章就介紹到這了,更多相關(guān)Python裝飾器重載內(nèi)置內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家! 

相關(guān)文章

  • pyqt6實(shí)現(xiàn)關(guān)閉窗口前彈出確認(rèn)框的示例代碼

    pyqt6實(shí)現(xiàn)關(guān)閉窗口前彈出確認(rèn)框的示例代碼

    本文主要介紹了pyqt6實(shí)現(xiàn)關(guān)閉窗口前彈出確認(rèn)框的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-02-02
  • python中l(wèi)eastsq函數(shù)的使用方法

    python中l(wèi)eastsq函數(shù)的使用方法

    這篇文章主要介紹了python中l(wèi)eastsq函數(shù)的使用方法,leastsq作用是最小化一組方程的平方和,下面文章舉例說明詳細(xì)內(nèi)容,具有一的參考價(jià)值,需要的小伙伴可以參考一下
    2022-03-03
  • python代碼制作configure文件示例

    python代碼制作configure文件示例

    這篇文章主要介紹了python代碼如何制作configure文件,需要的朋友可以參考下
    2014-07-07
  • python中的路徑拼接問題

    python中的路徑拼接問題

    這篇文章主要介紹了python中的路徑拼接問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • Python文件操作模擬用戶登陸代碼實(shí)例

    Python文件操作模擬用戶登陸代碼實(shí)例

    這篇文章主要介紹了Python文件操作模擬用戶登陸代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-06-06
  • python判斷是空的實(shí)例分享

    python判斷是空的實(shí)例分享

    在本篇內(nèi)容里小編給大家整理的是關(guān)于python怎么判斷是空的相關(guān)知識點(diǎn)內(nèi)容,需要的朋友們學(xué)習(xí)下。
    2020-07-07
  • Python中利用all()來優(yōu)化減少判斷的實(shí)例分析

    Python中利用all()來優(yōu)化減少判斷的實(shí)例分析

    在本篇文章里小編給大家整理的是一篇關(guān)于Python中利用all()來優(yōu)化減少判斷的實(shí)例分析內(nèi)容,有需要的朋友們可以學(xué)習(xí)下。
    2021-06-06
  • windows環(huán)境中利用celery實(shí)現(xiàn)簡單任務(wù)隊(duì)列過程解析

    windows環(huán)境中利用celery實(shí)現(xiàn)簡單任務(wù)隊(duì)列過程解析

    這篇文章主要介紹了windows環(huán)境中利用celery實(shí)現(xiàn)簡單任務(wù)隊(duì)列過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-11-11
  • Python?字符串使用多個(gè)分隔符分割成列表的2種方法

    Python?字符串使用多個(gè)分隔符分割成列表的2種方法

    本文主要介紹了Python?字符串使用多個(gè)分隔符分割成列表,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • 對python中類的繼承與方法重寫介紹

    對python中類的繼承與方法重寫介紹

    今天小編就為大家分享一篇對python中類的繼承與方法重寫介紹,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-01-01

最新評論