Ответ 1
Я считаю, что я нашел причину несоответствия благодаря issue14003. Похоже, что это связано с изменением API-интерфейса создания модуля от Python 2 до 3.
В Python 2 при построении модулей с Py_InitModule4
был доступен аргумент PyObject *self
, который мог бы иметь значение None
, если пожелаете, чтобы сгенерировали модули расширения, как описано:
Если
self
неNULL
, он будет передан функциям модуля в качестве их (иначеNULL
) первого параметра
Большинство встроенных стандартных библиотечных модулей по-видимому, выбрали этот путь, и поэтому результат 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_method
и builtin_function
на самом деле одна и та же структура, поэтому имеет смысл встроенные функции для совместного использования атрибута __self__
, найденного в методах.
Тип function
, с другой стороны, действительно не имеет смысла иметь его, поскольку он не используется каким-либо образом с типом method
.