Почему "функция" не является ключевым словом в Python?

Классы типа str или type

>>> type("pear")
<class 'str'>
>>> type(str)
<class 'type'>

доступны в Python:

>>> str
<class 'str'>
>>> type
<class 'type'>

Однако function классов и builtin_function_or_method не являются.

>>> def foo(): pass
... 
>>> type(foo)
<class 'function'>
>>> type(print)
<class 'builtin_function_or_method'>

Они отображаются как встроенные классы, но при попытке доступа к ним они вызывают ошибки имен:

>>> function
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'function' is not defined
>>> builtin_function_or_method
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'builtin_function_or_method' is not defined

Что особенного в function и builtin_function_or_method?

Ответы

Ответ 1

То, что вы видите, - это представление типа функции:

>>> from types import FunctionType
>>> repr(FunctionType)
"<class 'function'>"

Это "тип" функции, определенной с def или иначе:

>>> def f():
...     pass
... 
>>> type(f) is FunctionType
True
>>> type(lambda: None) is FunctionType
True

"Функция" сама по себе не является синтаксисом, потому что проще ввести "def".

Риторический вопрос: если def было именем, используемым для разрешения типа функции, то какой синтаксис вы бы использовали для фактического определения функции?

Ответ 2

Классы и функции имеют неотъемлемое имя:

>>> def foo():
...     pass
...
>>> foo
<function foo at 0x10f951400>
>>> foo.__name__
'foo'

Имя, прикрепленное к объекту, не зависит от имени, которое вы используете для доступа к объекту, но при определении функций (и классов) они одинаковы.

>>> bar = foo
>>> bar
<function foo at 0x10f951400>

Вы даже можете избавиться от переменной, которую используете для доступа к функции, если у вас есть ссылка где-то в другом месте:

>>> funcs = [foo]
>>> funcs[0]
<function foo at 0x10f951400>
>>> del foo
>>> foo
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'foo' is not defined
>>> funcs[0]
<function foo at 0x10f951400>
>>> funcs[0].__name__
'foo'

Встроенный тип функции таков: нет переменной, которая ссылается на нее, но она все еще существует и имеет имя __name__:

>>> def foo(): pass
...
>>> type(foo)
<class 'function'>
>>> type(foo).__name__
'function'

Ответ 3

Type Object возвращается из функции type() (или object.__class__).

Вы можете получить полный список этих объектов типа здесь.

Но вы также можете создать свой собственный:

>>> import types
>>> types.new_class('my_made_up_type')
<class 'types.my_made_up_type'>

Таким образом, это объект типа, возвращающий определенные объекты (например, встроенные функции) (а именно: types.BuiltinFunctionType), но эти объекты типа не являются встроенными классами, поэтому неудивительно, что они не определены в интерпретаторе.