object
我有一个关于Python中的类或对象到底是什么的问题。
据我所知,在 Python 中,一切都是由元类创建的type
(但从我接下来要解释的内容来看,这让我怀疑):
>>> str.__class__
<class 'type'>
>>> int.__class__
<class 'type'>
>>> bool.__class__
<class 'type'>
>>> float.__class__
<class 'type'>
>>> class A:
... pass
...
>>> A.__class__
<class 'type'>
>>> ClassName = type('ClassName', (), {})
>>> ClassName.__class__
<class 'type'>
另一方面object
,它是一个实例type
:
>>> object.__class__
<class 'type'>
>>> isinstance(object, type)
True
对我来说根本不起作用的是:
>>> isinstance(type, object)
True
如果它应该是一个实例,它怎么可能type
是一个实例?没有任何意义。看起来Python自相矛盾......object
object
type
除此之外,它object
是一个基类type
:
>>> type.__bases__
(<class 'object'>,)
但是根据 Python object
,它是一个实例,type
根据它,一个类 () 怎么可能从该类type
的实例 () 继承object
?
因此,基于此:type
and到底是什么object
?可以说,这两者中的哪一个是“真正的”元类或“创建类的类”?据我了解,它是type
:
type('MyClass', (), {})
出于对对象更多了解的好奇,似乎所有类都继承或继承自它:
>>> int.__bases__
(<class 'object'>,)
>>> bool.__bases__
(<class 'int'>,)
>>> str.__bases__
(<class 'object'>,)
>>> float.__bases__
(<class 'object'>,)
>>> class A:
... pass
...
>>> A.__bases__
(<class 'object'>,)
为什么会这样?
也许一个
很好的总结是:通常,在一种语言中支持 OOP 时,存在一个元类,其他类从该元类派生而来,而所有对象都从该根类派生而来。例如,在 Smalltalk 中分别有
Class
和Object
。好吧,我们可以认为在 Python 中它的等价物是type
andobject
,但是如果如上所述,一切都是对象,type
那么它也是对象,因此它应该派生自object
。既然object
它是一个类,它应该派生自type
... 这将我们带到哲学中的一个经典问题,这本质上是您的问题:Python 中的一切都围绕“对象”的概念展开,它是 Python 用于表示数据的抽象。Python 中的所有数据都由对象或它们之间的关系表示。
每个对象都具有三个特征:
一个身份:它对每个对象都是唯一的,只要它存在就永远不会改变。在 CPython 中使用对象的内存地址。它是身份运算符 (
is
) 比较的内容以及内置函数id()
返回的内容。值:对象所代表的数据,值可以在列表等可变对象中改变。在不可变对象如字符串之后不能修改对象的实例。
类型:对象的类型(或类)是它作为实例的类。一个类也是一个对象,因此有一个类型,这些对象的类型是
type
。它type
也是一个对象,它的类型也是type
,唯一具有此特性的对象。从概念上讲,由于 Python 2.2 的“类型”和“类”是相同的。
object
类
object
是 Python 中类层次结构的基础。所有类都是 的类的子类object
,因此所有对象都是 的实例object
。这个类包含一个类的基本骨架,每个类都有的基本方法,例如__getattribute__
,我们总是可以从子类调用的方法,例如在'__getattribute__
'的情况下,使私有属性成为不可能以我们坚持的方式存在于 Python 中...请记住,一个类本身也是一个对象,一个存储在内存中的对象,其中包含构建其他对象的指令。
type
在 C (
PyObject* PyType_Type
) 中定义,它是 CPython 中唯一的内置元类。元类只是一个类,其实例也是类。就像我们肯定一切都是对象一样,一切都有类型,是的,
object
也......但与 不同
object
的是,并非一切都是类型(或派生自type
):一切看起来都一团糟,看起来
type
和object
相互继承,但这并不是真的,实际上这在 OOP 中本质上是不可能的。此外,我们必须始终牢记,我们正处于 OOP 并不真正存在的水平,它正在被创建。CPython 是用 C 实现的,而 C 不理解 OOP。既不object
继承自此级别,type
也没有type
继承object
自此级别,根本没有继承。不仅仅是相互继承,发生的事情是它
object
是一个实例type
并type
派生自object
. 实际上,仍然存在一个循环关系,它在 C 级别通过几个步骤解决,中间有几个间接关系,我不打算讨论。在 Python 层面,答案开头的小段必须始终正确,以尊重数据模型:
type
所以它必须是对象才能存在。object
它是所有对象的基本类型,因此它是一种类型,并且作为一种类型,它必须是type
.如果我们从所有实现和概念细节中抽象出来,我们可以不打扰我们的存在,如下所示:
每个对象的基类是
object
(当然除了它自己的object
),总是,总是,总是:每个对象都有一个类型,它只是它作为实例的类,因此类型和类是等价的概念。到目前为止非常好,但是如果每个对象都有一个类型并且一个类也是一个对象,那么我们将什么类型分配给一个“类”对象?这正是它出现的地方
type
,它是每个“类”对象的类型,包括object
它type
本身。type
通过 builtin 暴露的类type()
允许我们动态创建新的类型/类,因为一个好的元类允许我们创建类的实例,但是有人猜到它type
为我们生成的类的基类是什么?始终牢记派生/继承与作为某事物的实例之间的区别。一件事是“作为 X 的一个实例”,另一件事是“作为一个派生自 X 的类”:
foo
是 的一个实例Foo
,但不从它继承,而是Bar
如果它派生自Foo
,但不是它的实例。概括
除了它自己的对象之外的每个对象都
object
派生自object
,否则它不存在。元类
type
作为存在的对象,派生自object
.元类
type
创建其他所有类,无一例外地从object
.所以它
object
不会从任何东西派生/继承,但type
它是object
.尽管它们是类,但它们的类型是
object
,所以它是唯一满足以下条件的类:type
type
type
因此我们可以认为一个类/类型是一个实例
type
并且总是派生自object
.多么有趣的一个问题。我参考语言的官方文档分享我的答案,但也基于我个人的经验在你的问题的最深层次。
实际上,根据语言文档https://docs.python.org/3/library/functions.html#object, object
object
是类类型的对象,并且是所有其他类的基础。这就是为什么所有的类,包括那些内置于语言中的类,例如int
、dict
、set
、list
等,都将对象作为它们的基类之一object
。毫无疑问,由于上述原因,这非常令人困惑。根据我的经验,这并不矛盾:根据文档,对象
object
是所有其他对象的派生类;我们可以进一步探索,我们会发现它type
是 的一个子类object
,object
但它不是type
. 因此,object
它是设计的实例(instance)type
,以表明它object
是一个类(或者,类类型的对象),并且所有类都是类型为type
(https://docs.python.org/3 /reference/datamodel.html ),即使object
它不是从object = type("object", bases=(), dict=some_dict)
. 类似地,它发生在type
.在这一点上没有进一步的混乱。对象
object
是所有类的基础,并且包含任何类的所有实例共有的方法,即使这些实例是类本身。当您在表单中调用它时object()
,它会返回一个没有特征或属性的对象(https://docs.python.org/3/library/functions.html#object),因此它不会创建类。对象type
是一个类,因此它的类型是它自己:type
. 使用三个参数调用它是创建类而不是声明class
https://docs.python.org/3/library/functions.html#type的动态方式。创建类的类是type
(是一个元类),因此所有类都是type
.