为什么+=在列表上表现得出乎意料?

为什么+=在列表上表现得出乎意料?

这个+=python中的运算符似乎意外地在列表上操作。有人能告诉我这是怎么回事吗?

class foo:  
     bar = []
     def __init__(self,x):
         self.bar += [x]class foo2:
     bar = []
     def __init__(self,x):
          self.bar = self.bar + [x]f = foo(1)g = foo(2)print f.barprint g.bar 

f.bar += [3]print f.barprint g.bar

f.bar = f.bar + [4]print f.barprint g.bar

f = foo2(1)g = foo2(2)print f.bar 
print g.bar

输出量

[1, 2][1, 2][1, 2, 3][1, 2, 3][1, 2, 3, 4][1, 2, 3][1][2]

foo += bar似乎影响到类的每个实例,而foo = foo + bar看上去就像我所期望的那样。

这个+=运算符被称为“复合赋值运算符”。



BIG阳
浏览 322回答 3
3回答

POPMUISE

一般的答案是+=试图调用__iadd__方法,如果无法使用该方法,则尝试使用__add__相反。所以问题在于这些特殊方法之间的区别。这个__iadd__特殊方法是用于就地添加的,即它对其作用的对象进行变异。这个__add__特殊方法返回一个新对象,并用于标准+接线员。所以当+=运算符用于具有__iadd__定义的对象被修改到位。否则,它将尝试使用普通的__add__并返回一个新对象。这就是为什么对于列表这样的可变类型+=更改对象的值,而对于元组、字符串和整数等不可变类型,则返回一个新对象(a += b变得等价于a = a + b).对于支持这两种类型的类型__iadd__和__add__因此,你必须小心使用哪一个。a += b会打电话__iadd__突变a,鉴于a = a + b将创建一个新对象并将其分配给a..他们不是同一个行动!>>> a1 = a2 = [1, 2]>>> b1 = b2 = [1, 2]>>> a1 += [3]          # Uses __iadd__, modifies a1 in-place>>> b1 = b1 + [3]       # Uses __add__, creates new list, assigns it to b1>>> a2[1, 2, 3]               # a1 and a2 are still the same list>>> b2[1, 2]                 # whereas only b1 was changed对于不可变类型(在该类型中,您没有__iadd__) a += b和a = a + b都是等价物。这就是让你使用的东西+=对于不可变的类型,这似乎是一个奇怪的设计决策,直到您考虑到否则您无法使用+=像数字这样的不可变的类型!
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python