CPython 如何将变量与值匹配?

How does CPython match variables to values?

根据我在其他论坛帖子上看到的,CPython处理变量的方式是,如果我错了请纠正我,虚拟机创建一个存储值的堆,变量名称,标识符是存储在该线程的堆栈中的某个位置。因此,如果 num = 5 在我的代码中,值 5 将位于堆中的某处,而字符串 num 将出现在堆栈中的某处。

我找不到的是 CPython 是如何知道如何从堆栈中匹配一些变量名作为其匹配值的。我知道它没有用户指针,那么它是如何工作的?

在Python中,每个变量都存储在字典中。

>>> def foo():
...   bar = 123
...   baz = 'Mike!'
...   print locals()
...
>>> foo()
{'bar': 123, 'baz': 'Mike!'}

locals() 方法 return 是在本地范围内创建的所有变量。

当你用 'num' 标记 5 时,有一个字典存储字符串 'num' 和它的关联值 5。 Python 对象都存储在堆中,即字典,字符串'num',数字5。它们都在堆中。

>>> num = 5
>>> print globals()
{'__builtins__': ..., 'num': 5, ...}

当您调用 Python 中的函数时,例如

foo(123, 456, name='Mike', is_valid=True)

Python 对待它就像

foo(*(123, 456), **{'name': 'Mike', 'is_valid': True})

映射到 following C code

PyObject_CallObject(PyObject* function, PyObject* arguments, PyObject* keywords)

foo 函数实际上是一个 Python 对象,参数和关键字也是。 arguments 是元组,而 keywords 是字典。 They are all Python objects!

那么栈帧上剩下的就是标准 C 函数的栈帧,其中包含 return 地址和指向 3 个 python 对象的指针。

如果你深入研究资源,你会发现 Python 是一部美丽的作品。

读取字典值

Python 字典是实现 Mapping protocol 的 Python 对象。字典的存储方式在实现内部。我已经链接到官方 API 以从字典中读取值。但这里有一个味道

 PyObject* PyMapping_GetItemString(PyObject *o, char *key) 

相当于Python中的o[key]。 Python字典在

中实现了上面的函数原型
 PyObject* PyDict_GetItemString(PyObject *p, const char *key)¶

PyDict_GetItem 的实现是 here 但我不熟悉它。我快速阅读了文件上的评论,你的问题的答案似乎是两者兼而有之。字典可以将它的值和键存储在一个块中,或者交换为单独存储它们。我的猜测是一个针对类数组索引器的情况进行了优化,而另一个更像是关联数组。