从我在其他论坛帖子上看到的,CPython处理变量的方式是,如果我错了,请纠正我,虚拟机创建一个存储值的堆,变量名称,标识符存储在某处在该线程的堆栈中。因此,如果num = 5
在我的代码中,则值5将位于堆中的某个位置,并且字符串num将出现在堆栈中的某处。
我找不到的是CPython如何知道如何匹配堆栈中的某些变量名称以获得匹配值。我知道它不是用户指针,所以它是如何工作的?
答案 0 :(得分:0)
在Python中,每个变量都存储在字典中。
>>> def foo():
... bar = 123
... baz = 'Mike!'
... print locals()
...
>>> foo()
{'bar': 123, 'baz': 'Mike!'}
locals()
方法返回在本地范围内创建的所有变量。
当你用'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})
PyObject_CallObject(PyObject* function, PyObject* arguments, PyObject* keywords)
即。 foo
函数实际上是一个Python对象,参数和关键字也是如此。 arguments
是元组,而keywords
是字典。 Ťhey are all Python objects!
那么堆栈帧上还剩下什么,只是一个标准的C函数的堆栈帧,它包含返回地址和指向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,但我不熟悉它。我快速阅读了有关该文件的评论,您的问题的答案似乎都是。字典可以将它的值和键存储在单个块中,或者交换以单独存储它们。我的猜测是针对类似数组索引器的情况进行优化,而另一种更像是关联数组。