【问题标题】:How does variable copying in Python exactly work?Python 中的变量复制究竟是如何工作的?
【发布时间】:2015-11-12 23:00:23
【问题描述】:

为什么会这样:

 >>> a = 1
 >>> b = a
 >>> a = 2
 >>> print(a)
 2
 >>> print(b)
 1

...但是:

 >>> a = [3, 2, 1]
 >>> b = a
 >>> a.sort()
 >>> print(b)
 [1, 2, 3]

我的意思是,为什么真正复制了变量而只引用了迭代器?

【问题讨论】:

  • 在我看来,这是学习 Python 最难的部分之一:学会区分获取现有对象并修改它和采用现有名称并使其指向不同的对象
  • @turbulencetoo:很简单。此处没有示例 copy 对象。对象可能有多个名称。名称可能在不同时间指代不同的对象。 This picture might provide an insight

标签: python variables reference


【解决方案1】:

变量不是“真正复制的”。变量是对象的名称,赋值运算符将名称绑定到运算符右侧的对象。更详细:

>>> a = 1 表示“将a 命名为引用对象1”。

>>> b = a 的意思是“将b 命名为引用a 当前引用的对象的名称。即1

>>> a = 2 表示“将a 命名为引用对象2 的名称”。这对任何其他碰巧引用1 现在引用的对象没有影响,例如b

在第二个示例中,ab 都是引用同一个列表对象的名称。 a.sort() 就地改变该对象,并且由于两个变量都引用同一个对象,因此在两个名称下都可以看到突变的效果。

【讨论】:

【解决方案2】:

将分配的变量视为指向保存值的内存位置的指针。您实际上可以使用id 获取内存位置。

a = 1
b = a

>>> id(a)
4298171608

>>> id(b)
4298171608  # points to the same memory location

a = 2
>>> id(a)
4298171584  # memory location has changed

对您的列表示例执行相同操作,您可以看到两者实际上都在对同一个对象进行操作,但不同的变量都指向同一个内存位置。

a = [3, 2, 1]
b = a
a.sort()

>>> id(a)
4774033312

>>> id(b)
4774033312  # Same object

【讨论】:

  • 请注意,id 返回内存位置是一个实现细节 - 对于常见的 C python 实现来说是正确的,但不能保证在所有实现中都是正确的。确实,如果两个对象的ids 相同,则对象相同。 id 对于像整数和字符串这样的不可变对象意味着什么是一个更复杂的问题 - 通常你不必关心它们,因为它们是不可变的。
【解决方案3】:

在您的第一个示例中,您在将 b 的值设为 a 后重新分配了 a 的值。所以 a 和 b 携带不同的值。

如果您将 a 重新分配给一个新的排序列表,而不是仅仅对其进行排序,那么在您的第二个示例中也会发生同样的情况。

a = [3,2,1]
b = a
a.sort()
print b
[1,2,3]

但是……

a = [3,2,1]
b = a
sorted(a)
print b
[3,2,1]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-01-26
    • 2019-10-12
    • 1970-01-01
    • 2020-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-16
    相关资源
    最近更新 更多