为啥`object`是`type`的实例而`type`是`object`的实例?

Posted

技术标签:

【中文标题】为啥`object`是`type`的实例而`type`是`object`的实例?【英文标题】:Why is `object` an instance of `type` and `type` an instance of `object`?为什么`object`是`type`的实例而`type`是`object`的实例? 【发布时间】:2021-04-15 18:51:51 【问题描述】:

我对 Python 3 中的 objecttype 类有点困惑。也许有人可以解决我的困惑或提供一些额外的信息。

我目前的理解是每个类(object 除外)都继承自一个名为 object 的基类。但是每个类(包括object)也是类type的一个实例,它是它自己和object的一个实例,也继承自object

我的问题是:

为什么objecttype 的实例并且type 继承自object,是否有原因/设计决策?对象的type/class 本身是否也是对象?

一个类 (type) 如何成为它自己的一个实例?

哪个是真正的基类objecttype? 我一直以为object会是最“基础”的类,但它似乎是type的一个实例,它是object的一个实例,它是type的一个实例,... 这个递归在哪里结束?

有没有可能说明objecttype类之间的关系?

我尝试在 Python 标准库的文档中查找 objecttype 的条目。

每个类(对象除外)都继承自对象。

>>> 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 Types and Objects

UPD:another link to the book。如果它也死了,请告诉我。

回答您问题的最重要部分:

对象的类型/类是否也是对象本身?

是的,根据第 1 章的规则 1:

“一切都是对象……我们定义的任何类都是对象,当然,这些类的实例也是对象。”

哪个是真正的基类objecttype

从第 2 章开始:

“这两个对象是 Python 中的原始对象。我们不妨一次只引入一个,但这会导致先有鸡还是先有蛋的问题——先引入哪个?这两个对象是相互依赖的——它们不能站立它们自己的,因为它们是根据彼此定义的。”

Luciano Ramalho 在他的《Fluent Python》一书中也说这种关系不能用 Python 表达(第 21 章):

"类对象和类型具有唯一的关系:对象是一个 type 的实例,type 是 object 的子类。这种关系 是“魔法”:它不能用 Python 表达,因为任何一个类都会 必须在另一个可以定义之前存在。事实上,类型是 自身的一个实例也很神奇。”

所以,对于你的问题:

类(类型)如何成为自身的实例?

Luciano 说它也不能用 Python 表达。

有没有可能说明对象和类型类之间的关系?

非常感谢在第 3 章中制作此插图的作者:

【讨论】:

遗憾的是,该图像缺少箭头,以反映 issubclass(object, object) 是真的这一事实。 @chepner 你有没有忘记每个类都是它自己的子类,对于object 类并不特别? 但是有一个箭头强调type 的类型为type。只是想知道为什么object 不是object 的子类没有得到同样的重视。 (也就是说,每个类都有一个父类;但object 是唯一的类,它是它自己的父类。) Cannata 所著书籍的链接似乎已失效。 object 不是它自己的父级,因为type 是它自己的类:对象是根,它没有父级。它是它自己的一个子类,就像class C 是它自己的一个子类一样。 class C 基础是 (object,),而对象基础是空的 (),如问题文本中的打印所示。【参考方案2】:

根据 Python Data Model,Python 中的一切都是对象,每个对象都有一个标识、一个类型和一个值。

object是所有对象的基类,type也是一个对象,所以它是object的一个实例,object本身也是如此。同样type 是所有对象类型的基类,所以object 的类型是typetype 本身也是如此。

这是我的理解,如有错误欢迎指出。

【讨论】:

【参考方案3】:

&lt;class 'type'&gt;是类object的元类,每个类(包括type)都直接或间接继承自object

如果您需要了解有关元类的更多信息,请点击此处https://realpython.com/python-metaclasses/

【讨论】:

谢谢!这篇文章真的很有帮助。但据我现在的理解:type 类不是“正常”元类,因为它们在实现级别上“作弊”,并且无法在纯 Python 中重现。

以上是关于为啥`object`是`type`的实例而`type`是`object`的实例?的主要内容,如果未能解决你的问题,请参考以下文章

isinstance(type, object) = True,为啥? [复制]

使用 Objective-C/Swift 单例模型,为啥我们要创建共享实例而不只是使用类方法? [复制]

Python元编程元类

不能用邮递员发帖,为啥?

096 元类

Java中的Class类的newinstance方法返回值为啥是object类型的?