这个程序的Python内存模型

在http://pythontutor.com/上运行时,我的查询是关于存储值和函数的符号的以下程序。

记忆模型

我的问题是:

  1. 在开始解释python程序之前,python执行模型如何在内存上查找上面的程序? 我如何可视化内存布局? 例如,c可执行文件具有代码/堆栈/堆/额外/数据段,仅作为示例,我不进行比较

  2. ‘const’是32/64位存储区的名称,存储值2,类型是否为整数?

  3. add()/ sub()/其他函数按照图表显示在Objects列中,那么,我如何感知函数存储为对象? 我如何想象它?

  4. 根据图表,op是一个指向函数sub()的函数指针吗?

每个C(编译语言)程序在执行之前都会在内存中加载代码/数据/堆栈/额外/堆段。 在开始解释python程序之前,python解释器是否为每个python程序创建了任何内存布局? 如果是,我如何可视化内存布局?

它有一种布局,但这里堆是最重要的部分,因为每个对象都放在堆中。 代码段仅仅是解释器,数据段也是解释器的内部状态,也是堆栈。

与Python程序相关的只是堆。 但布局本身就像任何其他程序一样。

const是32/64位存储区的名称,存储值2 ,类型是否为整数?

它是当前工作空间中的一个名称(这里:在模块的命名空间中),它本质上是一个dict,它在字符串和任意对象之间进行赋值。 在这种情况下,它使字符串const引用一个保存值2的整数对象。 (这个对象可以根据具体情况重新创建或重新使用;这没有区别,因为它是不可变的。)

add() / sub() /其他函数按照图表显示在Objects列中,那么,我如何感知函数存储为对象? 我如何想象它?

正如我对伊格纳西奥的回答所写的那样:

在函数的情况下,你有一个具有某些字段的对象,其中包含例如字节码的代码,它具有的参数数量等等。它甚至还有方法本身,例如内部调用的__get__()用于将方法绑定到对象,或__call__()用于实际函数调用,除了__format__()__repr__()等。

整数对象在内部某处有一个存储实际值的位置。 在Py2中的long()或Py3中的任何int()情况下,它存储数据以保存值(例如2 )以及它所需的长度。 此外,它有很多方法。 看看dir(2)的输出,看它有一堆方法,比如格式化, 算术等等。

根据图表, op是一个指向函数sub()的函数指针吗?

是的,是的。

有一个函数对象,它在内部知道它的原始名称是sub 。 但这种知识仅用于显示目的。

在您的情况下,它是从两个名称, opsub op 。 所以参考其中任何一个都有相同的结果。

请注意,本身没有“函数指针”,只有引用或名称,它们引用任何类型的对象。 对象的类型是固定的,但不是“引用的类型”(因为没有这样的东西)。

  1. 字典词典。 字典是Python中最重要的结构。

  2. 它是当前范围字典中条目的关键。 值是对象2

  3. 它不是函数是对象,而是某些对象是函数。 或数字。 或者词典。

  4. 它是当前范围字典中条目的关键。 该值为sub

  1. 在Python中,不要过多担心内存片段以及幕后发生的事情。 相反,环境(范围)更重要。 您包含的块和指针图是可视化内存的合理方法。 白色部分显示了全球环境的样子。 调用该函数时,将创建一个新的(蓝色)环境。

  2. const是一个变量。 Python中的变量是 动态输入,并可以存储任何东西。 实际上, Python整数不会溢出 ,并且可以存储超过2 64的数字。 在这种情况下, const是一个包含数字2的变量(带有令人困惑的名称)。

  3. 函数是可调用代码块的抽象概念。 您可以像任何其他值一样将其分配给变量。

  4. 你可以认为它是一个函数指针,如果它让你感觉舒服,但那么你将作为一个C程序员外出自己。 Python程序员只会说op将函数sub作为值。