x = x + 1和x + = 1之间的Python区别[重复]

Posted

技术标签:

【中文标题】x = x + 1和x + = 1之间的Python区别[重复]【英文标题】:Python Difference between x = x+1 and x += 1 [duplicate] 【发布时间】:2012-10-06 00:00:32 【问题描述】:

在Python中,写x = x+1x += 1之间有什么区别(语义、效率等)?

【问题讨论】:

【参考方案1】:

是的。根据 x 类的编码方式,短格式可以选择就地修改 x,而不是创建一个表示总和的新对象并将其重新绑定回相同的名称。如果您有多个变量都引用同一个对象 - 例如,列表:

>>> a = b = []
>>> a += [5]
>>> a
[5]
>>> b
[5]
>>> a = a + [5]
>>> a
[5, 5]
>>> b
[5]

发生这种情况是因为在幕后,操作员调用了不同的魔法方法:+ 调用 __add____radd__(预计不会修改它们的任何一个参数)和 += 尝试 __iadd__(这如果__iadd__ 不存在,则允许在退回到+ 逻辑之前修改self

【讨论】:

【参考方案2】:

它们对于整数和浮点数几乎相同,但对于lists

lis = lis+['foo'] 通过连接lis['foo'] 创建一个新列表,然后将结果分配给lis

和:

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

【讨论】:

【参考方案3】:

它们是不同的,因为++= 有不同的运算符。使用x = x + 1,解释器会将其视为x = x.__add__(1),而x += 1 将是x = x.__iadd(1),这样效率更高,因为它不一定需要复制x

【讨论】:

x += 1 实际上变成了x = x.__iadd__(1),而不仅仅是x.__iadd__(1) - 即使是selfi* 魔术方法仍有望返回它们的结果(重要的是,根据您链接的文档,它不必是 self)。另请参阅 Lattyware 的答案中它们的反汇编 - 两个版本都有 STORE_FAST @lvc 谢谢,我更新了我的答案。【参考方案4】:

是的,它们是编译成不同字节码的不同运算符:

>>> 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         

在这种情况下,它不会有很大的不同,因为ints 是不可变的。从理论上讲,它们可以以不同的方式实现(取决于解释器),但这不会改变它对值的操作方式。

一般来说,它们可以被实现来做完全不同的事情(+ 被魔术方法__add__()+=__iadd()__ 实现) - 例如,在大多数可变容器中,它会产生巨大的区别,如果你有不同的名字引用同一个对象:

>>> x = []
>>> y = x
>>> x += [1]
>>> y
[1]
>>> x = x + [1]
>>> y
[1]
>>> x
[1, 1]

您可以看到,当我们将x 分配给y 时,它们都指向同一个列表。当我们使用+= 时,我们扩展了列表并且两者都发生了变化。当我们为x 分配新值时,y 仍然指向原始值并保持不变。

【讨论】:

以上是关于x = x + 1和x + = 1之间的Python区别[重复]的主要内容,如果未能解决你的问题,请参考以下文章

x = x + 1和x + = 1之间的Python区别[重复]

求曲线 y = 1/(1+x^2) 和 x 轴之间的面积

CodeIgniter 错误报告 1.7.x 和 2.x 之间的区别

获取停止(第 x 行)和开始(第 x+1 行)之间的时间间隔

x*= 和 x=x* 之间的区别...?

std::atomic<int>:x.fetch_add(1) 和 x++ 之间的区别;