它们不必相同。
使用+ 运算符调用__add__ 方法,而使用+= 运算符调用__iadd__。调用这些方法之一时会发生什么完全取决于相关对象。
如果您使用x += y,但x 没有提供__iadd__ 方法(或该方法返回NotImplemented),则__add__ 用作fallback,这意味着@ 987654331@ 发生。
在列表的情况下,使用l += iterable 实际上是使用iterable 的元素扩展列表l。在您的情况下,字符串中的每个字符(它是一个可迭代的)都在 extend 操作期间附加。
演示1:使用__iadd__
>>> l = []
>>> l += 'table'
>>> l
['t', 'a', 'b', 'l', 'e']
演示 2:使用 extend 也是如此
>>> l = []
>>> l.extend('table')
>>> l
['t', 'a', 'b', 'l', 'e']
演示 3:添加一个列表和一个字符串会引发 TypeError。
>>> l = []
>>> l = l + 'table'
[...]
TypeError: can only concatenate list (not "str") to list
不使用+= 会在此处为您提供TypeError,因为只有__iadd__ 实现了扩展行为。
演示 4:常见陷阱:+= 不会构建新列表。我们可以通过使用is 运算符检查相同的对象身份来确认这一点。
>>> l = []
>>> l_ref = l # another name for l, no data is copied here
>>> l += [1, 2, 3] # uses __iadd__, mutates l in-place
>>> l is l_ref # confirm that l and l_ref are names for the same object
True
>>> l
[1, 2, 3]
>>> l_ref # mutations are seen across all names
[1, 2, 3]
但是,l = l + iterable 语法确实构建了一个新列表。
>>> l = []
>>> l_ref = l # another name for l, no data is copied here
>>> l = l + [1, 2, 3] # uses __add__, builds new list and reassigns name l
>>> l is l_ref # confirm that l and l_ref are names for different objects
False
>>> l
[1, 2, 3]
>>> l_ref
[]
在某些情况下,这可能会产生细微的错误,因为+= 变异原始列表,而
l = l + iterable 构建一个新列表和重新分配名称l。
奖金
Ned Batchelder's challenge to find this in the docs