简体   繁体   中英

Why does __self__ of built-in functions return the builtin module it belongs to?

Methods have an attribute, __self__ , that holds the instance to be passed when the underlying function gets invoked. Apparently, so do built-in functions.

In Python 3, they hold the module object:

>>> len.__self__
<module 'builtins' (built-in)>
>>> sys.getrefcount.__self__  # also for other builtin modules
<module 'sys' (built-in)>

In Python 2, on the other hand, they hold None :

>>> type(len.__self__)
<type 'NoneType'>
>>> sys.getrefcount.__self__
<type 'NoneType'>

Does anyone know why there's a discrepancy here? In addition to that, why do these even have a __self__ and aren't like Python level module functions that lack a __self__ attribute:

>>> from pprint import pprint
>>> pprint.__self__
AttributeError: 'function' object has no attribute '__self__'

I believe I've found the reason for the discrepancy thanks to issue14003 . It seems it is due to a change in the module creation API from Python 2 to 3.

In Python 2, during the construction of modules with Py_InitModule4 , a PyObject *self argument was available that could have the value of None if writters of extention modules wished, as documented:

If self is non- NULL , it will be passed to the functions of the module as their (otherwise NULL ) first parameter

Most of the built-in standard library modules apparently chose that path and as such the result of builtin_function.__self__ is None :

mod = Py_InitModule4("__builtin__", builtin_methods,
                     builtin_doc, (PyObject *)NULL,
                     PYTHON_API_VERSION);

In Python 3, the API for creating modules changed and that option disappeared. The function for creating modules, PyModule_Create2 , doesn't take a self argument that's allowed to be None . Instead, it calls PyModule_AddFunctions (which calls the internal _add_methods_to_object to add the functions to the module) and unconditionally sets the __self__ attribute on the builtin functions to be the module.

So that's why for len the builtins module is returned. AFAIK, it isn't used anywhere inside the function body so it's purpose isn't special in any way.


Props to @user2357112 for making me feel silly, builtin_method and builtin_function are actually the same struct so it makes sense for builtin functions to share the __self__ attribute found in methods.

The function type, on the other hand, really has no point in having it since it isn't shared in any way with the method type.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM