vin*_*ngo 6 python dynamic-typing python-internals
我读了这个问题,但它没有给我一个明确的答案: Python解释器如何寻找类型?
python解释器如何知道变量的类型?我不知道如何获得类型.我在这里看看幕后发生了什么.在下面的示例中,它如何将类int或string与我的变量相关联.
它是如何知道这是一个int:
>>> i = 123
>>> type(i)
<class 'int'>
Run Code Online (Sandbox Code Playgroud)
或那个字符串:
>>> i = "123"
>>> type(i)
<class 'str'>
Run Code Online (Sandbox Code Playgroud)
Mar*_*ers 11
它如何将类int或string与我的变量相关联
Python没有.变量没有类型.只有变量引用的对象具有类型.变量只是指向对象的名称.
例如,以下内容还显示了对象的类型,但不涉及任何变量:
>>> type(1)
<class 'int'>
>>> type('foobar')
<class 'str'>
Run Code Online (Sandbox Code Playgroud)
当您使用type(variable)时,variable表达的一部分,只是返回名称引用的对象,传递对象的type()功能.当使用1or时'foobar',表达式是生成对象的文字,然后传递给type()函数.
Python对象只是解释器内存中的数据结构; 在CPython C结构中使用.变量只是那些结构的引用(指针).调用CPython中的基本类型结构PyObject,这个结构有一个ob_type槽,告诉Python什么类型的东西.类型只是更多的C结构.
如果你想跟随CPython源代码,你可以从bltinmodule.c源代码开始(因为它type是一个内置名称),它定义type为PyType_Type结构.调用类型(type是型太)调用其tp_new功能,并且定义了作为所述函数.此函数使用一个参数处理调用,如下所示:PyType_Type type_new
/* Special case: type(x) should return x->ob_type */
{
const Py_ssize_t nargs = PyTuple_GET_SIZE(args);
const Py_ssize_t nkwds = kwds == NULL ? 0 : PyDict_Size(kwds);
if (PyType_CheckExact(metatype) && nargs == 1 && nkwds == 0) {
PyObject *x = PyTuple_GET_ITEM(args, 0);
Py_INCREF(Py_TYPE(x));
return (PyObject *) Py_TYPE(x);
}
Run Code Online (Sandbox Code Playgroud)
这x是PyObject你传入的对象; 注意,不是变量,而是对象!因此,对于1整数对象或'foobar'字符串对象,将Py_TYPE()返回宏结果.Py_TYPE是一个宏,只返回ob_type任何PyObject结构的值.
所以,现在你有两种类型的对象1或'foobar'; 你怎么看到<class 'int'>或<class 'str'>在你的翻译会议中?Python交互式解释器自动在任何表达式结果上使用该repr()函数.在用于PyType_Type定义的C结构中,PyType_Type结构被合并,因此该类型的所有插槽都是直接可用的; 我会在这里省略究竟如何是工作的.对于类型对象,使用repr()意味着调用该type_repr函数,该函数返回:
rtn = PyUnicode_FromFormat("<class '%s'>", type->tp_name);
Run Code Online (Sandbox Code Playgroud)
所以最后,type(1)获取->ob_type插槽,(原来是Python 3中的PyLong_Type结构,长篇故事),并且该结构的tp_name插槽设置为"int".
TL; DR:Python变量没有类型,它们只是指向对象的指针.对象具有类型,如果您在解释器中回显对象,Python解释器将遵循一系列间接引用来到达要打印的类型名称.