Python地址分配给变量

Posted

技术标签:

【中文标题】Python地址分配给变量【英文标题】:Python address allocation to variables 【发布时间】:2015-09-30 20:48:14 【问题描述】:

最初变量 a、b 和 c 都具有值 1 和相同的地址。当变量 a 增加 1 时,地址会改变,而变量 b 和 c 的地址保持不变。有人可以详细说明这个地址分配吗?

现在当变量 b 增加 1 并且 b 的地址现在等于 a 的地址时。有人也可以详细说明一下吗?

>>> a = 1
>>> b = a
>>> c = b
>>> a += 1
>>> print a,b,c
2 1 1
>>> id(a)
26976576
>>> id(b)
26976600
>>> id(c)
26976600
>>> b += 1
>>> print a,b,c
2 2 1
>>> id(c)
26976600
>>> id(b)
26976576
>>> id(a)
26976576

【问题讨论】:

请阅读nedbatchelder.com/text/names.html。另请注意,您问题的第二部分是实现细节 - CPython 实习生小整数,这不是您应该依赖的行为。 【参考方案1】:

您看到这个的原因是因为您正在考虑变量,abc 是对象,而实际上整数是您的示例的对象.当您键入id() 时,您正在查看的内存位置是int 对象1int 对象2 的位置,而不是变量名称abc.

在 python 中,名称绑定到对象。当您拥有像 lists 这样可变的类型并且您尝试复制它们时,这可能会出现问题。更改对象意味着当您轮询两个引用时,您会看到更改在两者中传播,这并不总是您想要的,除非您意识到它会导致很多调试问题。

回到您的示例,我在开头添加了两个id() 实例以显示整数对象12 的ID。这应该会为您澄清一些事情。

>>> a = 1
>>> b = a
>>> c = a
>>> id(a)
4298174296
>>> id(b)
4298174296
>>> id(c)
4298174296
>>> id(1)
4298174296
>>> id(2)
4298174272
>>> a += 1
>>> id(a)
4298174272
>>> id(b)
4298174296
>>> id(c)
4298174296
>>> b += 1
>>> print a, b, c
2 2 1
>>> id(c)
4298174296
>>> id(b)
4298174272
>>> id(a)
>>> 4298174272

如您所见,1a b c 的位置最初都相同,2 的位置不同。然后,当您更改a 的分配时,它指向2 的位置,而bc 仍然指向1。然后当你重新分配b 时,它也指向2 的位置,只留下c 指向1。

希望能为您澄清。

【讨论】:

【参考方案2】:

https://docs.python.org/2/c-api/int.html#c.PyInt_FromLong

当前的实现为 -5 到 256 之间的所有整数保留一个整数对象数组,当您在该范围内创建一个 int 时,实际上您只是获取对现有对象的引用。

另外,在 Python 中,整数来自一个不可变对象:PyIntObject。一旦你创建了一个PyIntObject,你就永远不会改变它的值,其他的只是参考。

【讨论】:

【参考方案3】:

值和内存地址都是误导性术语。想想对象、名称和 ID。首先将对象1 分配给名称abc。所以这个对象的ID可以通过所有的名字来获取。

在第二步中,您将一个新对象,即整数 2 和其他 ID 分配给名称 a

在第三步中,您还将对象integer 2 分配给b。这是 CPython 的一个实现细节,小整数只在内存中保存一次,因此通过名称 b 访问的对象及其 ID 与 a 相同。

【讨论】:

以上是关于Python地址分配给变量的主要内容,如果未能解决你的问题,请参考以下文章

如何将字典值分配给 Python 中的变量?

python 变量 赋值浅拷贝深拷贝

Python,将列表的最后三个元素分配给各个变量

无法将查询结果分配给 python 变量

将变量分配给python文本文件中的数据集

Python:使用 vars() 将字符串分配给变量