python2.x 和 python3 的現代類所有具有內建動作表示式呼叫的 x 類都不會觸發 getattr(和 getattribute)(參見 Python 的 getattr 和 getattribute 攔截內建操作)。
強制:表示強制型別轉換,當您使用加法(或連線)操作+時,不同的型別會觸發型別轉換或報錯。
內建操作呼叫模式:隱式呼叫,即呼叫表示式; 顯式呼叫,這是被呼叫方法的名稱。
描述:
內建操作的表示式呼叫在 python3 中不可用0 個委託,因為不會觸發 getattr(和 getattribute)
例
>>def tracecall(*args):跟蹤呼叫。python2.x 執行py2 的 getattr (截獲對 print() 和 + 等內建操作的表示式呼叫,並正確地委託給裝飾物件。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('禁止設定:'+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 '員工私人>電話號碼:'+str(self.phone)
def __add__(self,num):
self.phone+=num
#python2.x 執行python3.x 執行py3 的 getattr(它不會攔截對 print() 和 + 等內建操作的表示式呼叫),不能委託給裝飾物件。>trace=true
>sp1=staff_private('梯形圖讀取線',110)
setattr,oninstance 包裝,員工私人>電話號碼:110]。
py2 遺留類攔截內建操作表示式呼叫 - 隱式呼叫、print()。
>print(sp1)
getattr,__str__]
員工私人>電話號碼:110
py2 傳統類攔截內建操作表示式呼叫 - 隱式呼叫,+
>sp1+1
getattr,__coerce__]
getattr,__add__]
>print(sp1)
getattr,__str__]
員工私人>電話號碼:111
#python3.x 執行描述:python3.X 的裝飾器重載內建的操作運算子方法,以截獲裝飾類的內建表示式呼叫。>trace=true
>sp1=staff_private('梯形圖讀取線',110)
setattr,oninstance 包裝,員工私人>電話號碼:110]。
py3 不會攔截內建操作列印
>print(sp1)
_main__.accessctrl..ondecorator..oninstance object at 0x0000019736c2f4f0>
py3 不攔截內建操作 +
>sp1+1
traceback (most recent call last):
file "", line 1, in
sp1+1typeerror: unsupported operand type(s) for +:'oninstance' and 'int'
例如,過載 str (intercept print(), add (intercept +.
例
>>def tracecall(*args):跟蹤呼叫。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('禁止設定:'+attr)
else:setattr(self.__wrapped,attr,value)
print() 觸發 str (
def __str__(self):
tracecall('oninstance,__str__')
str() 觸發 str(
return str(self.__wrapped)
+ 觸發器新增 (
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 '員工私人>電話號碼:'+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 call print() 觸發 str (
setattr,oninstance 包裝,員工私人>電話號碼:110]。
print() 觸發 str (
>print(sp1)
oninstance,__str__]
staff_private,__str__]
員工私人>電話號碼:110
+ 觸發器新增 (
>sp1+1
oninstance,__add__,1]
staff_private,__add__,1]
>print(sp1)
oninstance,__str__]
staff_private,__str__]
員工私人>電話號碼:111