python id()函数实现
python id() function implementation
python内置函数是如何实现的?其中一些像 issubclass
是对象方法的包装器。
关于 id() Documentation 说:
对于CPython,id(x)是存储x的内存地址。
文档中说到id()时,other places不要再说了!
那么 id() 是如何实现的呢?我认为它与CpythonAPI中对象的任何方法无关。为了拥有它们,我使用了 dir(x)
:
foo = [1,2,3]
dir(foo)
>> ['__add__',
'__class__',
'__contains__',
'__delattr__',
'__delitem__',
'__dir__',
'__doc__',
'__eq__',
'__format__',
'__ge__',
'__getattribute__',
'__getitem__',
'__gt__',
'__hash__',
'__iadd__',
'__imul__',
'__init__',
'__init_subclass__',
'__iter__',
'__le__',
'__len__',
'__lt__',
'__mul__',
'__ne__',
'__new__',
'__reduce__',
'__reduce_ex__',
'__repr__',
'__reversed__',
'__rmul__',
'__setattr__',
'__setitem__',
'__sizeof__',
'__str__',
'__subclasshook__']
python 有多种实现。在cpython中,所有的对象都有一个标准的header,id就是那个header的内存地址。对对象的引用是指向它们的对象头的 C 指针(与 id 相同的内存地址)。您不能使用 dunder 方法来查找对象,因为您需要对象指针来查找 dunder 方法。
Python被编译成字节码,那个字节码被C执行。当你调用一个像id
这样的函数时,那个函数可以是更多的字节码,但也可以是一个C函数。在 bltinmodule.c
中搜索“builtin_id”,您将看到 id(some_object)
.
的 C 实现
static PyObject *
builtin_id(PyModuleDef *self, PyObject *v)
/*[clinic end generated code: output=0aa640785f697f65 input=5a534136419631f4]*/
{
PyObject *id = PyLong_FromVoidPtr(v);
if (id && PySys_Audit("builtins.id", "O", id) < 0) {
Py_DECREF(id);
return NULL;
}
return id;
}
id
函数使用 PyObject *v
调用,一个指向应获取其 id 的对象的指针。 PyObject
是所有 python 对象使用的标准对象头。它包括确定对象真正是什么类型所需的信息。 id
函数将对象指针转换为具有 PyLong_FromVoidPtr
的 python 整数(python int 的名称“long”有点历史)。这是您在 python 级别看到的 ID。
你可以获得cpython source on github and you can read up on C in the python docs at Extending and Embedding the Python Interpreter and Python/C API Reference Manual
python内置函数是如何实现的?其中一些像 issubclass
是对象方法的包装器。
关于 id() Documentation 说:
对于CPython,id(x)是存储x的内存地址。
文档中说到id()时,other places不要再说了!
那么 id() 是如何实现的呢?我认为它与CpythonAPI中对象的任何方法无关。为了拥有它们,我使用了 dir(x)
:
foo = [1,2,3]
dir(foo)
>> ['__add__',
'__class__',
'__contains__',
'__delattr__',
'__delitem__',
'__dir__',
'__doc__',
'__eq__',
'__format__',
'__ge__',
'__getattribute__',
'__getitem__',
'__gt__',
'__hash__',
'__iadd__',
'__imul__',
'__init__',
'__init_subclass__',
'__iter__',
'__le__',
'__len__',
'__lt__',
'__mul__',
'__ne__',
'__new__',
'__reduce__',
'__reduce_ex__',
'__repr__',
'__reversed__',
'__rmul__',
'__setattr__',
'__setitem__',
'__sizeof__',
'__str__',
'__subclasshook__']
python 有多种实现。在cpython中,所有的对象都有一个标准的header,id就是那个header的内存地址。对对象的引用是指向它们的对象头的 C 指针(与 id 相同的内存地址)。您不能使用 dunder 方法来查找对象,因为您需要对象指针来查找 dunder 方法。
Python被编译成字节码,那个字节码被C执行。当你调用一个像id
这样的函数时,那个函数可以是更多的字节码,但也可以是一个C函数。在 bltinmodule.c
中搜索“builtin_id”,您将看到 id(some_object)
.
static PyObject *
builtin_id(PyModuleDef *self, PyObject *v)
/*[clinic end generated code: output=0aa640785f697f65 input=5a534136419631f4]*/
{
PyObject *id = PyLong_FromVoidPtr(v);
if (id && PySys_Audit("builtins.id", "O", id) < 0) {
Py_DECREF(id);
return NULL;
}
return id;
}
id
函数使用 PyObject *v
调用,一个指向应获取其 id 的对象的指针。 PyObject
是所有 python 对象使用的标准对象头。它包括确定对象真正是什么类型所需的信息。 id
函数将对象指针转换为具有 PyLong_FromVoidPtr
的 python 整数(python int 的名称“long”有点历史)。这是您在 python 级别看到的 ID。
你可以获得cpython source on github and you can read up on C in the python docs at Extending and Embedding the Python Interpreter and Python/C API Reference Manual