x + = y和x = x + y之间的差异

时间:2015-02-15 18:46:40

标签: python python-3.x

我有这个python代码

x = [1, 2, 3]
y = x
x += [4]
>>> print(y)
[1, 2, 3, 4]

所以,这是因为x is yTrue,如果我更改x,我会更改y

但是当我这样做时:

x = [1, 2, 3]
y = x
x = x + [4]
>>> print(y)
[1, 2, 3]

>>> id(x) == id(y)
False

我想知道有什么区别。我认为x += 1x = x+1的简写,但显然必须存在差异。

当我尝试上述字符串时,我更加困惑:

name = 'John'
name_2 = name
name += ' Doe'

>>> print(name_2)
'John'

所以我认为+=的效果取决于左边的对象,如果它是可变的?

2 个答案:

答案 0 :(得分:1)

“左侧”对象处理运算符(通常参见r运算符形式);在这种情况下,它是Inplace Operator

  

10.3.2。就地操作员

     

许多操作都有“就地”版本。下面列出的函数提供了比通常语法更原始的就地运算符访问;例如,语句x += y等同于x = operator.iadd(x, y) ..

实际结果由“x”对象确定,如果它处理__iadd__(例如,与列表一样突变)或仅__add__(例如,新的结果对象,与字符串一样) - 选择要使用的协议以及为赋值返回的值由operator.iadd本身 1 确定。

因此,对于某些对象,x += y ~~ x = x + y的简写只有 为真 - 尤其是那些不可变且[仅]实现__add__的对象。

请参阅How are Python in-place operator functions different than the standard operator functions?


1 从语义上讲,operator.iadd函数的工作方式如下:

if x.__iadd__:
    x.__iadd__(y)        # side-effect performed on x,
    return x             # returns original-but-modified object
else
    return x.__add__(y)  # return new object,
                         # __add__ should not have side-effects

答案 1 :(得分:0)

像@BrenBarn所说,如果左侧对象是可变的,它将执行就地操作。否则,将返回一个新副本,因为它被复制,他们的ID将不再匹配。

在背景中,它类似于:

>>> import copy
>>> y = [1,2,3]
>>> x = y
>>> x+=[4]
>>> y
[1, 2, 3, 4]
>>> x = copy.copy(y) #perhaps even a deepcopy()? Don't know.
>>> y
[1, 2, 3, 4]
>>> x
[1, 2, 3, 4]
>>> x += [5]
>>> y
[1, 2, 3, 4]
>>> x
[1, 2, 3, 4, 5]

编辑1:

class test():
    def __init__(self, ll):
        self.a = ll
    def __add__(self, other):
        return test(ll=self.a+other.a)

>>> a = test([[1,2],[3,4]])
>>> a.a
[[1, 2], [3, 4]]
>>> x = test([[1,2],[3,4]])
>>> x += a
>>> x.a
[[1, 2], [3, 4], [1, 2], [3, 4]]
>>> a.a
[[1, 2], [3, 4]]
>>> x.a[2][0] = 7
>>> x.a
[[1, 2], [3, 4], [7, 2], [3, 4]]
>>> a.a
[[7, 2], [3, 4]]