Python 交替引用新实例

标签 python python-2.7

这些天我一直在玩 Python,我意识到 Python 如何将 id(address) 分配给新实例(int 和 list)的一些有趣方式。

例如,如果我使用一个数字(或两个不同的数字)来调用 id 函数,它会返回相同的结果。例如

>>> id(12345)
4298287048
>>> id(12345)
4298287048
>>> id(12345)
4298287048
>>> id(12342) #different number here, yet still same id
4298287048

此外,当我先声明变量然后用它调用 id() 时,结果会像这样交替出现。

>>> x = []; id(x)
4301901696
>>> x = []; id(x)
4301729448
>>> x = []; id(x)
4301901696
>>> x = []; id(x)
4301729448

有人可以解释一下这背后的 Python 工作吗?另外,有没有一本书或一个网站可以让我了解 Python 的这一部分(分配内存地址、幕后工作等),因为我从 python documentation 中找不到什么?

最佳答案

您正在创建一个新对象没有任何其他引用,并且当对象在 id() 完成后再次销毁时,Python 会重新使用内存位置。在 CPython 中,id() 的结果 恰好 是对象的内存位置。来自id() function documentation :

CPython implementation detail: This is the address of the object in memory.

id(12345) 行创建了一个新的 int() 实例;因为它作为参数绑定(bind)到 id() 它有 1 个引用。 id() 确定内存位置,并返回该结果。在返回时,参数被清理并且对 int() 实例的引用计数下降到 0,Python 将其清理。内存被释放。

下一行创建一个新的 int() 实例。在同一位置有可用内存,因此可以重复使用。

相反,当您第一次绑定(bind)没有名称的新对象时,您创建了一个对该对象的额外引用并且它没有被清除。内存未释放,新对象将不得不使用新的内存地址。

这部分也有记录,同样来自 id() 文档:

This is an integer (or long integer) which is guaranteed to be unique and constant for this object during its lifetime. Two objects with non-overlapping lifetimes may have the same id() value.

强调我的。

重新绑定(bind)时(x = []x 已经设置时)Python 首先 创建一个新对象,然后 重新绑定(bind) x 以指向该新对象。这会在新列表创建后解除旧列表的绑定(bind)。这意味着当创建新的列表对象时,旧的内存位置仍然被占用。

将其映射到特定步骤:

  1. 您使用 id() == 4301901696 创建了一个对象。
  2. 4301901696 绑定(bind)到 x -> 4301901696 的引用计数为 1。
  3. 您使用 id() == 4301729448 创建了一个对象。
  4. 4301901696 未绑定(bind) x4301901696 的引用计数降至 0 并从内存中清除。
  5. 4301729448 绑定(bind)到 x4301729448 的引用计数为 1。
  6. 您创建了一个新对象,4301901696 为空,因此新对象得到 id() == 4301901696
  7. 4301729448 未绑定(bind) x4301729448 的引用计数降至 0 并从内存中清除。
  8. 4301901696 绑定(bind)到 x4301901696 的引用计数为 1。
  9. 等等

这也是文档的一部分,assignment statement documenation告诉您订单分配发生在:

An assignment statement evaluates the expression list [...] and assigns the single resulting object to each of the target lists, from left to right.

其中 表达式列表= 符号右侧的所有内容。

关于Python 交替引用新实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24086367/

相关文章:

python - 覆盆子PI B +上的python 2.7 cvtColor错误215

python - 为什么图形大小(y 轴)在此示例中波动?

python - 为什么plt.imshow()在matplotlib中不起作用

python - 如果元组被描述为序列类型,为什么长度为 1 的元组被视为标量?

python - python中使用for语句的无限循环

python - 执行元组算术的优雅方式

python - 如何在 GAE Python 中查询结构化属性内的计算属性

python - 如何创建适用于 Linux/Windows(任何版本)的 Odoo 安装程序

使用 Popen 启动的 Python 服务存在日志记录 stderr 和 stdout 重定向问题

Python 脚本返回旧的 MySQL 值(直到重新启动)