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
被分配给名称 a
、b
和 c
。所以这个对象的ID可以被所有的名字访问到。
在第二步中,您分配一个新对象,整数 2,以及名称 a
的其他 ID。
在第三步中,您也将对象 integer 2
分配给 b
。这是 CPython 的一个实现细节,小整数只在内存中保存一次,因此对象及其 ID,即通过名称 b
达到的与通过 a
相同。
您看到这个的原因是因为您在考虑变量,a
、b
和 c
是对象,而实际上它是作为示例对象的整数。当您键入 id()
时,您正在查看的内存位置是 int
对象 1
和 int
对象 2
的位置,而不是变量名称 a
、b
和 c
。
在python中,名称绑定到对象。当你有像 lists
这样可变的类型并且你试图复制它们时,这可能会有问题。更改对象意味着当您轮询两个引用时,您会看到更改在两个引用中传播,这并不总是您想要的,除非您意识到它可能会导致很多调试问题。
回到你的例子,我在开头添加了两个id()
的实例来显示整数对象1
和2
的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
如您所见,1
和 a b c
的位置最初都是相同的,而 2
的位置不同。然后,当您更改 a
的分配时,它指向 2
的位置,而 b
和 c
仍然指向 1
。然后,当您重新分配 b
时,它也指向 2
的位置,只留下 c
指向 1.
希望这能为您澄清。
最初变量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
被分配给名称 a
、b
和 c
。所以这个对象的ID可以被所有的名字访问到。
在第二步中,您分配一个新对象,整数 2,以及名称 a
的其他 ID。
在第三步中,您也将对象 integer 2
分配给 b
。这是 CPython 的一个实现细节,小整数只在内存中保存一次,因此对象及其 ID,即通过名称 b
达到的与通过 a
相同。
您看到这个的原因是因为您在考虑变量,a
、b
和 c
是对象,而实际上它是作为示例对象的整数。当您键入 id()
时,您正在查看的内存位置是 int
对象 1
和 int
对象 2
的位置,而不是变量名称 a
、b
和 c
。
在python中,名称绑定到对象。当你有像 lists
这样可变的类型并且你试图复制它们时,这可能会有问题。更改对象意味着当您轮询两个引用时,您会看到更改在两个引用中传播,这并不总是您想要的,除非您意识到它可能会导致很多调试问题。
回到你的例子,我在开头添加了两个id()
的实例来显示整数对象1
和2
的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
如您所见,1
和 a b c
的位置最初都是相同的,而 2
的位置不同。然后,当您更改 a
的分配时,它指向 2
的位置,而 b
和 c
仍然指向 1
。然后,当您重新分配 b
时,它也指向 2
的位置,只留下 c
指向 1.
希望这能为您澄清。