我想继承一个不可变类型或实现我自己的类型,其行为类似于int
,如以下控制台会话所示:
>>> i=42
>>> id(i)
10021708
>>> i.__iadd__(1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'int' object has no attribute '__iadd__'
>>> i += 1
>>> i
43
>>> id(i)
10021696
毫不奇怪,int
个对象没有__iadd__()
方法,但将+=
应用于一个不会导致错误,相反,它显然会创建一个新的int
和也不知何故神奇地将它重新分配给扩充赋值语句中给出的名称。
是否可以创建一个用户定义的类或内置不可变类的子类,如果是这样,怎么做?
答案 0 :(得分:14)
只是不要实施__iadd__
,而只是__add__
:
>>> class X(object):
... def __add__(self, o):
... return "added"
>>> x = X()
>>> x += 2
>>> x
'added'
如果没有x.__iadd__
,Python只会将x += y
计算为x = x + y
doc。
答案 1 :(得分:3)
当它看到i += 1
时,Python会尝试调用__iadd__
。如果失败,它会尝试拨打__add__
。
在这两种情况下,调用的结果都将绑定到名称,即它将尝试i = i.__iadd__(1)
然后i = i.__add__(1)
。
答案 2 :(得分:2)
使用__iadd__()
的返回值。您不需要返回要添加的对象;你可以创建一个新的并返回它。实际上,如果对象是不可变的,那么有到。
import os.path
class Path(str):
def __iadd__(self, other):
return Path(os.path.join(str(self), str(other)))
path = Path("C:\\")
path += "windows"
print path
答案 3 :(得分:-1)
class aug_int:
def __init__(self, value):
self.value = value
def __iadd__(self, other):
self.value += other
return self
>>> i = aug_int(34)
>>> i
<__main__.aug_int instance at 0x02368E68>
>>> i.value
34
>>> i += 55
>>> i
<__main__.aug_int instance at 0x02368E68>
>>> i.value
89
>>>