Python地址分配给变量

Python address allocation to variables

最初变量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

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

The current implementation keeps an array of integer objects for all integers between -5 and 256, when you create an int in that range you actually just get back a reference to the existing object.

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

值和内存地址都是误导性术语。考虑对象、名称和 ID。首先,对象 1 被分配给名称 abc。所以这个对象的ID可以被所有的名字访问到。

在第二步中,您分配一个新对象,整数 2,以及名称 a 的其他 ID。

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

您看到这个的原因是因为您在考虑变量,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.

希望这能为您澄清。