I am under an impression that python built-in functions are wrappers around object methods.
About id() Documentation says that:
For CPython, id(x) is the memory address where x is stored.
When talking about id(), other places in documentation do not say anything more!
I expect that id() should use one of the dunder methods or attributes of variable x that is passed to it under the hood! It must be one that you can see when you do
dir(x)
Which one is it? For example:
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__']
CodePudding user response:
There are multiple implementations of python. In cpython, all objects have a standard header and the id is the memory address of that header. References to objects are C pointers to their object header (that same memory address that is the id). You can't use a dunder method to find an object because you need the object pointer to find the dunder methods.
Python is compiled into byte code and that byte code is executed by C. When you call a function like id
, that function can be more byte code, but it can also be a C function. Search for "builtin_id" in bltinmodule.c
and you'll see the C implementation of 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;
}
The id
function is called with PyObject *v
, a pointer to the object whose id should be taken. PyObject
is the standard object header used by all python objects. It includes information needed to figure out what type the object really is. The id
function turns the object pointer into a python integer with PyLong_FromVoidPtr
(the name "long" for a python int is somewhat historical). That's the id you see at the python level.
You can get the 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