Python 3: почему "объект" является экземпляром "тип", а "тип" является экземпляром "объект"?
Изменить: я не думаю, что это настоящий дубликат Что такое метаклассы в Python? хотя на мой вопрос частично ответ в самом конце длинного комментария.
Связанный вопрос касается метаклассов в целом. Мой вопрос о конкретном type
метакласса. И из того, что я знаю после прочтения ответов, метакласс type
не может быть реализован на чистом Python. Поэтому мой вопрос касается не только "Что такое метаклассы?", Более того, он касается отношения type
/object
и того, как метакласс может создавать себя, что реализуется путем "обмана" на уровне реализации.
Также для людей, которые не знакомы с концепцией метаклассов, оба вопроса кажутся совершенно не связанными.
Начальное сообщение:
Я немного сбит с толку насчет классов object
и type
в Python 3. Может быть, кто-то может прояснить мою путаницу или предоставить некоторую дополнительную информацию.
Мое текущее понимание:
Каждый класс (кроме object
) наследуется от базового класса, называемого object
. Но каждый класс ( в том числе object
) также является экземпляр класса type
, который является экземпляром себя и object
, а также наследует от object
. 😕😕😕
Мои вопросы:
-
Есть ли причина/проектное решение, почему object
является экземпляром type
а type
наследуется от object
? Должен ли type
/класс объекта быть самим объектом?
-
Как класс (type
) может быть экземпляром самого себя?
-
Какой из них является реальным object
или type
базового класса?
Я всегда думал, что object
будет самым "фундаментальным" классом, но, похоже, это экземпляр type
, который является экземпляром object
, который является экземпляром type
,... Где заканчивается эта рекурсия?
-
Есть ли возможность проиллюстрировать связь между object
и type
класса?
Что я пробовал:
Я просмотрел записи object
и type
в Документации стандартной библиотеки Python.
Как это проверить:
Каждый класс (кроме объекта) наследуется от объекта.
>>> for x in object, int, float, str, list, dict:
... print(f'{x.__name__:6}: {x.__bases__}')
...
object: ()
int : (<class 'object'>,)
float : (<class 'object'>,)
str : (<class 'object'>,)
list : (<class 'object'>,)
dict : (<class 'object'>,)
Каждый класс является экземпляром класса type
.
>>> for x in object, int, float, str, list, dict:
... print(f'{x.__name__:6}: {x.__class__}')
...
object: <class 'type'>
int : <class 'type'>
float : <class 'type'>
str : <class 'type'>
list : <class 'type'>
dict : <class 'type'>
type
это экземпляр самого себя.
>>> type.__class__
<class 'type'>
type
также наследуется от object
.
>>> type.__bases__
(<class 'object'>,)
Также
>>> isinstance(object, type)
True
>>> isinstance(type, object)
True
>>> isinstance(type, type)
True
>>> isinstance(object, object)
True
>>> issubclass(type, object)
True
>>> issubclass(object, type)
False
Ответы
Ответ 1
Ответы на все ваши вопросы можно найти в этой книге: Типы и объекты Python
Самые важные части, чтобы ответить на ваши вопросы:
- Должен ли тип/класс объекта быть самим объектом?
Да, в соответствии с правилом 1 из главы 1:
"Все является объектом... Любые классы, которые мы определяем, являются объектами, и, конечно, экземпляры этих классов также являются объектами".
- Какой из них является реальным
object
или type
базового класса?
Из главы 2:
"Эти два объекта являются примитивными объектами в Python. Мы могли бы также вводить их по одному, но это привело бы к проблеме курицы и яйца - которую нужно сначала ввести? Эти два объекта взаимозависимы - они не могут стоять сами по себе, поскольку они определены в терминах друг друга ".
Также Лучано Рамальо в своей книге "Свободный Python" говорит, что это отношение не может быть выражено в Python (глава 21):
"Объекты и тип классов имеют уникальное отношение: объект является экземпляром типа, а тип является подклассом объекта. Это отношение является" магическим ": оно не может быть выражено в Python, поскольку один класс должен существовать до того, как другой сможет быть определенным. Тот факт, что тип является экземпляром самого себя, также является волшебным ".
Итак, на ваш вопрос:
- Как класс (тип) может быть экземпляром самого себя?
Лучано говорит, что это не может быть выражено и в Python.
- Есть ли возможность проиллюстрировать связь между объектом и типом класса?
Большое спасибо автору, который сделал эту иллюстрацию в главе 3:
Ответ 2
<class 'type'>
является метаклассом object
класса, и каждый класс (включая type
) наследуется прямо или косвенно от object
.
Если вам нужно узнать больше о метаклассах, поищите здесь https://realpython.com/python-metaclasses/
Ответ 3
Согласно Python Data Model, все в Python является объектом, и каждый объект имеет идентичность, тип и значение.
object
является базовым классом для всех объектов, type
также является объектом, поэтому он является экземпляром object
, и то же самое для самого object
. Также type
является базовым классом всех типов объектов, поэтому тип object
равен type
, и то же самое для самого type
.
Это мое понимание, пожалуйста, укажите на любые ошибки.