Python x = x+1 和 x += 1 的区别
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12905338/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Python Difference between x = x+1 and x += 1
提问by John
In Python, is there any difference (semantics, efficiency, etc.) between writing x = x+1and x += 1?
在 Python 中,编写x = x+1和x += 1?之间有什么区别(语义、效率等)?
采纳答案by lvc
Yes. Depending on how the class of xis coded, the short form has the option to modify x in-place, instead of creating a new object representing the sum and rebinding it back to the same name. This has an implication if you have multiple variables all referring to the same object - eg, with lists:
是的。根据类的x编码方式,简短形式可以选择就地修改 x,而不是创建一个表示总和的新对象并将其重新绑定回相同的名称。如果您有多个变量都指向同一个对象,这就会产生影响——例如,使用列表:
>>> a = b = []
>>> a += [5]
>>> a
[5]
>>> b
[5]
>>> a = a + [5]
>>> a
[5, 5]
>>> b
[5]
This happens because behind the scenes, the operators call different magic methods: +calls __add__or __radd__(which are expected not to modify either of their arguments) and +=tries __iadd__(which is allowed to modify selfif it feels like it) before falling back to the +logic if __iadd__isn't there.
这是因为在幕后,运营商调用不同的魔术方法:+电话__add__或__radd__(这是预期不对其进行修改其参数),并+=尝试__iadd__(这是不允许修改self,如果它感觉就像是)回落至之前+如果逻辑__iadd__ISN没有。
回答by Gareth Latty
Yes, they are different operators that compile to different bytecode:
是的,它们是编译为不同字节码的不同运算符:
>>> import dis
>>> def test1(x):
... x = x + 1
...
>>> def test2(x):
... x += 1
...
>>> dis.dis(test1)
2 0 LOAD_FAST 0 (x)
3 LOAD_CONST 1 (1)
6 BINARY_ADD
7 STORE_FAST 0 (x)
10 LOAD_CONST 0 (None)
13 RETURN_VALUE
>>> dis.dis(test2)
2 0 LOAD_FAST 0 (x)
3 LOAD_CONST 1 (1)
6 INPLACE_ADD
7 STORE_FAST 0 (x)
10 LOAD_CONST 0 (None)
13 RETURN_VALUE
In this case, it won't make a huge difference as ints are immutable. In theory they could be implemented in different ways (depending on the interpreter), but that won't change the way it operates on the value.
在这种情况下,它不会产生巨大的差异,因为ints 是不可变的。理论上,它们可以以不同的方式实现(取决于解释器),但这不会改变它对值的操作方式。
In general, they can be implemented to do completely different things (+being implemented by the magic method __add__()and +=with __iadd()__) - in most mutable containers, for example, it makes a huge difference, if you have different names referencing the same object:
一般来说,它们可以被实现来做完全不同的事情(+由魔法方法__add__()和+=with 实现__iadd()__)——例如,在大多数可变容器中,如果你有不同的名称引用同一个对象,它会产生巨大的差异:
>>> x = []
>>> y = x
>>> x += [1]
>>> y
[1]
>>> x = x + [1]
>>> y
[1]
>>> x
[1, 1]
You can see that when we assign xto y, they both point to the same list. When we use +=, we extend the list and both change. When we assign a new value to x, ystill points to the original and remains unchanged.
您可以看到,当我们分配x给 时y,它们都指向同一个列表。当我们使用 时+=,我们扩展了列表并且两者都发生了变化。当我们为 分配新值时x,y仍指向原始值并保持不变。
回答by Ashwini Chaudhary
They are almost same for integers and floats, but for lists:
它们对于整数和浮点数几乎相同,但对于lists:
lis = lis+['foo']creates a new list by concatenating lisand ['foo']and then assigns the result to lis
lis = lis+['foo']通过连接创建一个新的列表lis和['foo'],然后将结果赋给lis
and :
和 :
lis += [foo]is equivalent to lis.extend([foo])
lis += [foo]相当于 lis.extend([foo])
>>> lis = [1,2,3]
>>> id(lis)
3078880140L
>>> lis += ['foo'] #or lis.extend(['foo'])
>>> id(lis) #same object
3078880140L
>>> lis = [1,2,3]
>>> id(lis)
3078880076L
>>> lis = lis+['foo']
>>> id(lis) #new object
3078880012L
回答by Brendan Long
They are different because there are seperate operators for +and +=. With x = x + 1, the interpreter will treat it like x = x.__add__(1), while x += 1will be x = x.__iadd(1), which can be much more efficient because it doesn't necessarily need to make a copy of x.
他们是不同的,因为对于单独的运营商+和+=。使用x = x + 1,解释器会将其视为x = x.__add__(1),而x += 1将是x = x.__iadd(1),这可能会更有效率,因为它不一定需要复制x.

