对Python的id()感到困惑

时间:2015-11-19 10:35:48

标签: python python-3.x memory-management identity

我可以理解以下定义:

  

每个对象都有一个标识,一个类型和一个值。对象的身份   一旦创建就永远不会改变;你可能会认为它是   对象在内存中的地址。 is运算符比较了标识   两个对象; id()函数返回表示其的整数   身份。

我认为上面的定义在创建“某事”时有效,例如:

>>> a = 0
>>> id(a)
1720438480

但我不明白:

>>> id(1)
1720438512
>>> b = 1
>>> id(b)
1720438512

我还没有创造任何东西;那么整数“1”怎么能有一个ID呢?这是否意味着只要我在Python Shell中“提及”1,就会将其分配给内存地址?另外,这是否意味着因为ID在其生命周期中永远不会改变,并且因为我的计算机内存有限,如果我反复询问独特事物的id(),我最终会得到类似“内存不足”的消息? (它无法重新分配内存,因为其他人的生命周期尚未结束。)

或者,从另一方面展示我的耳朵:

>>> id(something_1)
some unique memory address
>>> id(something_2)
some unique memory address
>>> ...

在哪一点重新分配内存?也就是说,

>>> my_variable = something_1
>>> id(my_variable)

会提供与id(something_1)不同的ID吗?

1 个答案:

答案 0 :(得分:4)

通常,只要您使用整数或字符串或任何其他文字,Python就会在内存中为您创建一个新对象。保证在对象的生命周期内具有相同的id,即,其引用计数不为零。

当你写下这样的东西时:

>>> id(1000)
140497411829680

Python创建整数1000并返回其id(CPython中对象的内存地址)。完成此操作后,整数对象1000的引用计数为零,并将其删除。这可以确保您只能通过编写id(something)(并且不将任何变量名称绑定到对象)来保持填充内存。

通常情况下,您无法预测重用何时会发生,但在我的Python shell中,它会非常一致地发生:

>>> id(1000)
140697307078576
>>> id(1001)
140697307078576
>>> id(1002)
140697307078576
>>> id(1003)
140697307078576

您可以看到,在创建每个新整数时,会反复使用相同的内存地址。但是,如果您阻止引用计数降至零,则可以看到使用了新内存:

>>> a = 1000
>>> id(a)
140697307078576
>>> b = 1001
>>> id(b)
140697306008368

在CPython中,整数-5到255是特殊情况,因为它们总是存在(因此在Python运行时期间始终具有相同的id)。这是一种优化,可以避免重复创建和破坏常用的整数。