1 python運算符重載之字符串顯示和右側加法
1.1 重載字符串顯示
1.1.1 str和repr
python調用prin()t時,自動調用__str__和__repr__,
python調用str()時,自動調用__str__和__repr__,
python調用repr()時,自動調用__repr__,不調用 str。
終端用__str__,開發時用__repr__。
自定義__str__和__repr__時,必須返回字符串。
>>> class MyAdd:def __init__(self,value=0):self.data=valuedef __add__(self,other):self.data+=other
>>> class MyAddRepr(MyAdd):def __repr__(self):return 'MyAddRepr({})'.format(self.data)
>>> ma=MyAdd(1)
>>> print(ma)
<__main__.MyAdd object at 0x03869C90>
>>> mar=MyAddRepr(1)
# print 自動調用 __repr__
>>> print(mar)
MyAddRepr(1)
# str repr 自動調用 __repr__
>>> str(mar),repr(mar)
('MyAddRepr(1)', 'MyAddRepr(1)')>>> class MyAddStr(MyAdd):def __str__(self):return 'MyAddStr({})'.format(self.data)
>>> mas=MyAddStr(2)
# print 自動調用 __str__
>>> print(mas)
MyAddStr(2)
# str 自動調用 __str__
# repr 不會調用 __str__
>>> str(mas),repr(mas)
('MyAddStr(2)', '<__main__.MyAddStr object at 0x03869CD0>')>>> class MyAddBoth(MyAdd):def __str__(self):return 'MyAddBothstr({})'.format(self.data)def __repr__(self):return 'MyAddBothrepr({})'.format(self.data)>>> mab=MyAddBoth(3)
# print str 自動調用 __str__
# repr 自動調用 __repr__
>>> print(mab)
MyAddBothstr(3)
>>> str(mab),repr(mab)
('MyAddBothstr(3)', 'MyAddBothrepr(3)')
1.1.2 自定義repr
當print對象在頂層時會調用自定義__str__,非頂層時調用默認調用內容或調用__repr__。
所以,建議自定義__repr__,來統一攔截print(),str(),repr()操作。
>>> class MyPrintStr:def __init__(self,val):self.val=valdef __str__(self):return str(self.val)
>>> class MyPrintRepr:def __init__(self,val):self.val=valdef __repr__(self):return str(self.val)
# 實例非頂層時print時用默認打印,或者repr,而不會用str
>>> mpsl=[MyPrintStr(1),MyPrintStr(2)]
>>> mprl=[MyPrintRepr(1),MyPrintRepr(2)]
>>> print(mpsl)
[<__main__.MyPrintStr object at 0x009F8370>, <__main__.MyPrintStr object at 0x009F8430>]
>>> print(mprl)
[1, 2]
1.2 重載右側和原處加法
1.2.1 radd
實例在加號左側,自動調用 add,
實例在加號右側,自動調用 radd,
>>> class MyRadd:def __init__(self,val):self.val = valdef __add__(self,other):print('add',self.val,other)return self.val+otherdef __radd__(self,other):print('radd',self.val,other)return other+self.val
>>> x=MyRadd(8)
>>> y=MyRadd(9)
# 實例 在加號左邊, 自動調用 __add__
>>> x+1
add 8 1
9
# 實例 在加號右邊, 自動調用 __radd__
>>> 1+y
radd 9 1
10
# 兩個實例相加時, 先調用 add 再調用 radd
>>> x+y
add 8 <__main__.MyRadd object at 0x00A23A30>
radd 9 8
17# return 類實例時,需要類型測試isinstance,避免嵌套循環
>>> class MyRaddIf:def __init__(self,val):self.val = valdef __add__(self,other):print('add',self.val,other)if isinstance(other,MyRaddIf):other=other.valreturn MyRaddIf(self.val+other)def __radd__(self,other):print('radd',self.val,other)return MyRaddIf(other+self.val)def __repr__(self):return '<MyRaddIf:{}>'.format(self.val)>>> x=MyRaddIf(8)
>>> y=MyRaddIf(9)
>>> print(x+10)
add 8 10
<MyRaddIf:18>
>>> print(10+y)
radd 9 10
<MyRaddIf:19>
>>> z=x+y
add 8 <MyRaddIf:9>
>>> print(z)
<MyRaddIf:17>
#>>> print(z)#注釋 if isinstance(other,MyRaddIf) 時,發生嵌套
#<MyRaddIf:<MyRaddIf:17>>
>>> print(z+10)
add 17 10
<MyRaddIf:27>
>>> print(z+z)
add 17 <MyRaddIf:17>
<MyRaddIf:34>
>>> class MyRadd:def __init__(self,val):self.val = valdef __add__(self,other):print('add',self.val,other)return self.val+other
>>> x=MyRadd(8)
>>> x+1
add 8 1
9
# 沒有radd時,實例在右側會報錯
>>> 1+x
Traceback (most recent call last):File "<pyshell#127>", line 1, in <module>1+x
TypeError: unsupported operand type(s) for +: 'int' and 'MyRadd'
1.2.2 iadd
python的+=優先調用__iadd___,沒有再調用_add__。
>>> class MyIadd:def __init__(self,val):self.val=valdef __iadd__(self,other):self.val+=otherreturn self
# += 調用 __add__
>>> x=MyIadd(5)
>>> x+=1
>>> x.val
6
>>> class MyIadd:def __init__(self,val):self.val=valdef __add__(self,other):self.val+=otherreturn self
# += 調用 __add__
>>> x=MyIadd(5)
>>> x+=1
>>> x.val
6
>>> class MyIadd:def __init__(self,val):self.val=valdef __add__(self,other):print('__add__')self.val+=otherreturn selfdef __iadd__(self,other):print('__iadd__')self.val+=otherreturn self
# += 優先調用 __iadd__
>>> x=MyIadd(5)
>>> x+=1
__iadd__