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