- 此问题在此处已有答案**:
10年前关闭了。
- 可能重复:**
Assignment of objects and fundamental types
a = [1,2,3]
b = a
print b is a
这段代码打印True。为什么?"is"只在两个变量指向同一个对象时才返回True,而在这种情况下,它们是具有相同值的不同对象。"=="将返回True,但"is"不应该返回。
然而,自从
b.reverse()
print a,b
打印[3,2,1][3,2,1],似乎在解释器看来,它们是同一个对象,对b的操作会自动在a上执行。再次问一下,为什么?我以前从未见过这样的事情发生。
6条答案
按热度按时间ymzxtsji1#
这是实际发生的情况:
以及类似于:
何时使用
copy
模块:有关详情:
kq4fsx7k2#
当你执行
a = [1, 2, 3]
时,你将名称a
绑定到一个列表对象;当你执行b = a
时,你将名称b
绑定到任何a
--在本例中是列表对象。因此,它们是相同的......一个对象可以有多个名称。值得阅读Python Data Model。如果你想复制你的listobj,那么你可以看
b = a[:]
来使用slice创建一个浅副本,或者copy.copy
来创建一个浅副本(应该可以在任意对象上工作),或者copy.deepcopy
来创建一个深副本。您还将注意到CPython中缓存短字符串/小整数的一些令人惊讶的特性...
wwtsj6pe3#
它们实际上引用了同一个对象。
试试这个:
您将看到a和b都发生了更改,并且彼此仍然相同。
r8xiu3jd4#
这段代码打印True。为什么?
因为...
仅当两个变量指向同一对象时,"is"才返回True
如果它们命名相同的对象。"指向"是一个粗俗的术语,暗指一个低得多的编程模型。
在这里它们是具有相同值的不同对象。
不,他们不是。
在Python中,
b = a
的意思是"b
将不再是它当前命名的任何东西的名称,而成为a
当前命名的任何东西的名称"。同一个对象,而不是副本。在Python中,不会隐式地复制内容。
打印[3,2,1][3,2,1],似乎就解释器而言,它们是同一个对象
因为他们是。
并且在B上的操作将自动在A上执行。
因为它们是同一个物体。
再说一遍,为什么?
再说一遍,因为他们是。
...这就好像你想到了每一个明显的测试确认的行为,但拒绝拒绝拒绝拒绝你的核心假设,一旦每一个测试相矛盾,即使没有任何文献支持你的核心假设(因为事实上它是错误的)。
我以前从没见过这种事。
那么你以前肯定没有在Python中测试过类似的东西,因为Python中一直都是这样的,甚至在编程语言中也不是那么奇怪; Java对所有非基元类型的东西都做同样的事情,C#对类(引用类型)也做同样的事情,同时做你对结构(值类型)显然期望的事情,这就是所谓的"引用语义",这绝不是一个新的想法。
oymdgrw75#
我不确定列表的工作原理是否相同,但请看numpy.array()教程中关于浅拷贝和深拷贝的内容:http://www.scipy.org/Tentative_NumPy_Tutorial#head-1529ae93dd5d431ffe3a1001a4ab1a394e70a5f2
a = b
只是创建了一个对同一对象的新引用。要获得一个真实的的副本,你可能会发现列表对象有一些类似于b = a.copy()
链接中的深度复制示例的东西。然后你可以说有两个引用具有相同值的两个独立对象。而且我认为大多数OO语言都是这样工作的,因为
=
只是创建一个新的引用,而不是一个新的对象。tkqqtvp16#
您正在比较对同一个
list
的引用。如果执行以下操作:你应该得到一个假。