【问题标题】:Confused about Python’s id() [duplicate]对 Python 的 id() 感到困惑 [重复]
【发布时间】:2016-02-21 10:49:32
【问题描述】:

我能理解下面的定义:

每个对象都有一个标识、一个类型和一个值。对象的身份 一旦创建就永远不会改变;你可能会认为它是 对象在内存中的地址。 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?

【问题讨论】:

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


【解决方案1】:

一般来说,只要您使用整数、字符串或任何其他文字,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)。这是为了避免重复创建和销毁常用整数的优化。

【讨论】:

  • 嗨,亚历克斯。如果有一个虚拟内存并且程序被多次换入/换出怎么办?不会改变同一个变量的物理内存地址吗?
  • CPython 不使用垃圾收集来清除未引用的对象。 引用计数下降到 0 的那一刻对象被删除。所以是的,id(1000) 将创建一个值为 1000 的 int 对象,唯一的引用是堆栈,id() 为该对象生成一个值,该对象从堆栈中清除并立即删除,因为引用计数为现在是 0。Python 确实有一个垃圾收集器,但它所负责的只是打破循环引用。
  • 小数范围为from -5 through to 256
猜你喜欢
  • 2015-02-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-09
  • 1970-01-01
  • 2020-08-21
  • 2018-08-15
相关资源
最近更新 更多