Как реализовать "__iadd__()" для неизменяемого типа?
Я хотел бы создать подкласс неизменяемого типа или реализовать свой собственный, который ведет себя как 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
а также каким-то волшебным образом переназначает его на имя, указанное в расширенном операторе присваивания.
Можно ли создать пользовательский класс или подкласс встроенного неизменяемого класса, который делает это, и если да, то как?
4 ответа
Возвращаемое значение __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
Просто не реализуй __iadd__
, но только __add__
:
>>> class X(object):
... def __add__(self, o):
... return "added"
>>> x = X()
>>> x += 2
>>> x
'added'
Если нет x.__iadd__
Питон просто вычисляет x += y
как x = x + y
док.
Когда он видит i += 1
Пифон попробует позвонить __iadd__
, Если это не удастся, он попытается позвонить __add__
,
В обоих случаях результат вызова будет привязан к имени, т.е. i = i.__iadd__(1)
а потом i = i.__add__(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
>>>