为什么__self__的内置函数会返回它所属的内置模块?

时间:2017-03-20 16:33:01

标签: python python-2.7 python-3.x python-internals

方法有一个属性__self__,用于保存在调用基础函数时要传递的实例。显然,内置函数也是如此。

在Python 3中,它们包含模块对象:

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

另一方面,在Python 2中,他们持有None

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

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

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

1 个答案:

答案 0 :(得分:9)

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

在Python 2中,在使用Py_InitModule4构建模块期间,如果需要扩展模块的写入,则PyObject *self参数可以具有None的值,如下所示: / p>

  

如果self为非NULL,则会将其作为其(NULL}第一个参数

传递给模块的函数

大多数内置标准库模块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的功能不会使self参数被允许为None。相反,它调用PyModule_AddFunctions(调用内部_add_methods_to_object将函数添加到模块中)并无条件地将内置函数的__self__属性设置为模块。

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

支持@ user2357112道具让我感到愚蠢,builtin_methodbuiltin_function实际上是the same struct所以内置函数分享方法中的__self__属性是有意义的

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