Python 3: почему "объект" является экземпляром "тип", а "тип" является экземпляром "объект"? - программирование
Подтвердить что ты не робот

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
4b9b3361

Ответ 1

Ответы на все ваши вопросы можно найти в этой книге: Типы и объекты Python

Самые важные части, чтобы ответить на ваши вопросы:

  • Должен ли тип/класс объекта быть самим объектом?

Да, в соответствии с правилом 1 из главы 1:

"Все является объектом... Любые классы, которые мы определяем, являются объектами, и, конечно, экземпляры этих классов также являются объектами".

  • Какой из них является реальным object или type базового класса?

Из главы 2:

"Эти два объекта являются примитивными объектами в Python. Мы могли бы также вводить их по одному, но это привело бы к проблеме курицы и яйца - которую нужно сначала ввести? Эти два объекта взаимозависимы - они не могут стоять сами по себе, поскольку они определены в терминах друг друга ".

Также Лучано Рамальо в своей книге "Свободный Python" говорит, что это отношение не может быть выражено в Python (глава 21):

"Объекты и тип классов имеют уникальное отношение: объект является экземпляром типа, а тип является подклассом объекта. Это отношение является" магическим ": оно не может быть выражено в Python, поскольку один класс должен существовать до того, как другой сможет быть определенным. Тот факт, что тип является экземпляром самого себя, также является волшебным ".

Итак, на ваш вопрос:

  • Как класс (тип) может быть экземпляром самого себя?

Лучано говорит, что это не может быть выражено и в Python.

  • Есть ли возможность проиллюстрировать связь между объектом и типом класса?

Большое спасибо автору, который сделал эту иллюстрацию в главе 3:

relation between object, type and other classes

Ответ 2

<class 'type'> является метаклассом object класса, и каждый класс (включая type) наследуется прямо или косвенно от object.

Если вам нужно узнать больше о метаклассах, поищите здесь https://realpython.com/python-metaclasses/

Ответ 3

Согласно Python Data Model, все в Python является объектом, и каждый объект имеет идентичность, тип и значение.

object является базовым классом для всех объектов, type также является объектом, поэтому он является экземпляром object, и то же самое для самого object. Также type является базовым классом всех типов объектов, поэтому тип object равен type, и то же самое для самого type.

Это мое понимание, пожалуйста, укажите на любые ошибки.