我有这个python代码
x = [1, 2, 3]
y = x
x += [4]
>>> print(y)
[1, 2, 3, 4]
所以,这是因为x is y
是True
,如果我更改x
,我会更改y
但是当我这样做时:
x = [1, 2, 3]
y = x
x = x + [4]
>>> print(y)
[1, 2, 3]
和
>>> id(x) == id(y)
False
我想知道有什么区别。我认为x += 1
是x = x+1
的简写,但显然必须存在差异。
当我尝试上述字符串时,我更加困惑:
name = 'John'
name_2 = name
name += ' Doe'
>>> print(name_2)
'John'
所以我认为+=
的效果取决于左边的对象,如果它是可变的?
答案 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)
在背景中,它类似于:
>>> 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]]