为什么 __self__ of built-in functions return 它所属的内置模块?

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

方法有一个属性,__self__,它保存着调用底层函数时要传递的实例。显然,内置函数也是如此。

在Python3中,他们持有模块对象:

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

在Python2中,另一方面,他们持有None:

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

有谁知道为什么这里会出现差异?除此之外,为什么这些甚至有一个 __self__ 而不像 Python 级别的模块函数缺少 __self__ 属性:

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

感谢 issue14003,我相信我已经找到了差异的原因。似乎是由于模块创建 API 从 Python 2 更改为 3。

在 Python 2 中,在使用 Py_InitModule4 构建模块期间,一个 PyObject *self 参数可用,如果扩展模块的编写者,该参数的值可能为 None希望,如文件所示:

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

大多数内置标准库模块 apparently chose that path 因此 builtin_function.__self__ 的结果是 None:

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

在 Python 3 中,用于创建模块的 API 发生了变化,该选项消失了。创建模块的函数,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 将函数添加到模块)并无条件地将内置函数的 __self__ 属性设置为模块。

这就是 len 返回 builtins 模块的原因。 AFAIK,它没有在函数体内任何地方使用,所以它的目的在任何方面都不特别。


@user2357112 让我觉得很傻的道具,builtin_methodbuiltin_function 实际上是 the same struct 所以内置函数共享找到的 __self__ 属性是有意义的在方法中。

另一方面,function 类型实际上没有任何意义,因为它不以任何方式与 method 类型共享。