1

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

现在,当变量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 
+0

请阅读http://nedbatchelder.com/text/names.html。另请注意,问题的第二部分是实现细节 - CPython实施小整数,这不是您应该依赖的行为。 – jonrsharpe

回答

0

您看到这个的原因是因为您在考虑变量a,bc作为对象,实际上它们是您的示例的对象中的整数。你正在寻找,当你键入id()在存储位置是为int对象1位置和int对象2,而不是变量名abc

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

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

>>> 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.

希望能够为您澄清它。

1

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

当前实现保持整数对象为-5和256之间的所有整数数组,当你在这个范围内创建一个int,你其实只是回到现有的引用目的。

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

1

值和内存地址都是误导性的术语。考虑对象,名称和ID。首先将对象1分配给名称a,bc。所以这个对象的ID可以通过所有的名字到达。

在第二步中,将一个新对象(整数2)与其他ID分配到名称a

在第三步中,您还将对象integer 2也指定为b。这是CPython的一个实现细节,小整数只在内存中保存一次,因此名称为b的对象及其ID为a