语法
object.__iadd__(self, other)
Python__iadd__() 魔法实现了原地加法 x += y ,将操作数加在一起,并将结果分配给左边的操作数。这个操作也被称为 增强的算术赋值.该方法只是返回分配给第一个操作数的新值。
- 当你调用
x += y时,Python 首先尝试调用x.__iadd__(y)。 - 如果这一点没有实现,它就会尝试正常的添加方式
[x.__add__(y)](https://blog.finxter.com/python-__add__/ "Python __add__() Magic Method"). - 如果这一点也没有实现,它就会尝试反向加法
[y.__radd__(x)](https://blog.finxter.com/python-__rxadd__-magic-method/ "Python __radd__() Magic Method")与互换的操作数。
然后将结果赋值给第一个操作数 x。如果这些操作都没有实现,Python 会引发一个TypeError 。
我们把这称为 "Dunder Method",即*"Double UnderscoreMethod"(也称为"Magic Method")*。
重写__iadd__的基本例子
在下面的代码例子中,你创建了一个类Data 并定义了神奇的方法__iadd__(self, other) 。
- "self"参数是每个方法的默认参数,它指的是被调用的对象--在我们的例子中,是就地操作的第一个操作数。
- 原地方法的 "其他 "参数指的是第二个操作数,即原地操作中的
yx += y。
该操作的返回值返回一个假的字符串'finxter 42' ,并分配给第一个操作数。在实践中,这将是原地加法的结果。
class Data:
def __iadd__(self, other):
return 'finxter 42'
x = Data()
y = Data()
x += y
print(x)
# finxter 42
没有 __iadd__() 的原地加法
要在一个自定义类上支持原地加法,你不必覆盖原地__iadd__() 方法。因为如果这个方法没有被定义,Python 会返回到正常的__add__() 方法,并将其结果分配给第一个操作数。
下面是一个例子:
class Data:
def __add__(self, other):
return 'finxter 42'
x = Data()
y = Data()
x += y
print(x)
# finxter 42
没有 __iadd__() 和 __add__() 的原地加法
要在一个自定义类上支持原地加法x += y ,你甚至不需要覆盖任何x.__iadd__(y) 或x.__add__(y) 方法。如果这两个方法都没有定义,Python 会回到反向的 [y.__radd__(x)](https://blog.finxter.com/python-__rxadd__-magic-method/ "Python __radd__() Magic Method")方法,并将其结果分配给第一个操作数。
这里有一个例子,你为第一个操作数创建了一个自定义类,不支持任何加法操作。然后你为第二个操作数定义一个自定义类,该类定义了__radd__() 方法。对于原地操作,Python 返回到在第二个操作数上定义的__radd__() 方法,并将其分配给第一个操作数x 。
class Data_1:
pass
class Data_2:
def __radd__(self, other):
return 'finxter 42'
x = Data_1()
y = Data_2()
x += y
print(x)
# finxter 42
TypeError: +=的操作数类型不支持
如果你试图执行原地加法x += y ,但是既没有定义x.__iadd__(y) ,也没有定义x.__add__(y) ,更没有定义y.__radd(x) ,Python 会引发一个 "TypeError: unsupported operand type(s) for +="。要解决这个错误,只需在执行原地操作之前定义这些方法中的任何一个。
class Data:
pass
x = Data()
y = Data()
x += y
输出
Traceback (most recent call last):
File "C:\Users\xcent\Desktop\code.py", line 8, in <module>
x += y
TypeError: unsupported operand type(s) for +=: 'Data' and 'Data'