这完全取决于对象i。
=调用__iadd__ method(如果存在 – 回到__add__如果不存在),而调用__add__ method1。
从API的角度来看,__iadd__应该用于修改可变对象(返回被突变的对象),而__add__应该返回一个新的实例。对于不可变对象,两个方法都返回一个新实例,但__iadd__将把新实例放在当前命名空间中,其名称与旧实例相同。这就是为什么
i = 1
i += 1
似乎增加i。在现实中,你得到一个新的整数,并将其分配给“顶部”i – 失去一个引用旧的整数。在这种情况下,i = 1与i = i 1完全相同。但是,对于大多数可变对象,它是一个不同的故事:
作为具体示例:
a = [1, 2, 3]
b = a
b += [1, 2, 3]
print a #[1, 2, 3, 1, 2, 3]
print b #[1, 2, 3, 1, 2, 3]
相比:
a = [1, 2, 3]
b = a
b = b + [1, 2, 3]
print a #[1, 2, 3]
print b #[1, 2, 3, 1, 2, 3]
注意在第一个例子中,因为b和一个引用相同的对象,当我使用= on b,它实际上改变b(和一个看到的变化 – 毕竟,它引用相同的列表)。然而,在第二种情况下,当I do b = b [1,2,3]时,这取得b是引用的列表,并且将其与新列表[1,2,3]链接。然后,它将当前命名空间中的连接列表存储为b – 不考虑前面的行是什么。
1在表达式x y中,如果没有实现x .__ add__,或者如果x .__ add __(y)返回NotImplemented,x和y有不同的类型,则x y尝试调用y.__radd__(x).因此,
foo_instance = bar_instance
如果Foo不实现__add__或__iadd__,那么这里的结果是相同的
foo_instance = bar_instance .__ radd __(bar_instance,foo_instance)