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 但我不熟悉它。我快速阅读了文件上的评论,你的问题的答案似乎是两者兼而有之。字典可以将它的值和键存储在一个块中,或者交换为单独存储它们。我的猜测是一个针对类数组索引器的情况进行了优化,而另一个更像是关联数组。
根据我在其他论坛帖子上看到的,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 但我不熟悉它。我快速阅读了文件上的评论,你的问题的答案似乎是两者兼而有之。字典可以将它的值和键存储在一个块中,或者交换为单独存储它们。我的猜测是一个针对类数组索引器的情况进行了优化,而另一个更像是关联数组。