Python 3: почему `object` является экземпляром` type`, а `type` экземпляром` object`? - PullRequest
10 голосов
/ 20 апреля 2019

Изменить: Я не думаю, что это настоящий дубликат Что такое метаклассы в 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

Ответы [ 2 ]

5 голосов
/ 20 апреля 2019

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

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

  • Имеет ли тип / класс объекта также сам объект?

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

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

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

Из главы 2:

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

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

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

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

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

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

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

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

relation between object, type and other classes

0 голосов
/ 20 апреля 2019

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

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

...