Python 中类型和对象的先有鸡还是先有蛋的悖论
Chicken or Egg paradox with type and object in Python
我记得学过 type
是它自己的实例,所有新式 classes 都继承自 object
,所以我开始胡闹:
issubclass(type, object) # True
issubclass(object, type) # False
# issubclass(cls, cls) is always True
type(type) is type # True
type(object) is type # True
总而言之,type
与任何新样式 class 一样是 object
的子 class,并且与任何 class 一样, type
和 object
都是 type
的实例。这是一张方便的图片:
在此声明我不是程序员,对 Python 的基本机制知之甚少,所以如果我听起来很蠢,请多多包涵。通常必须在其实例之前创建 class。然而,superclass 通常必须在它的 subclass 之前创建。将这些通用的 Python 规则应用于 type
和 object
会产生明显的先有鸡还是先有蛋的悖论。
那么这些 class 中哪些是先制作的?我还怀疑因为这些 classes 是用低级语言实现的,所以它们不必遵循 Python 规则。
在Python中,一切皆对象:
7
是类型 int
的对象。
'foo'
是 str
类型的对象。
None
是 NoneType
类型的对象。
- 如果你定义了一个class
class Foo: pass
,那么Foo
就是一个class
类型的对象。您从 class 构造的任何对象 Foo()
都是类型 Foo
的对象。
- 如果你将一个函数定义为
def f(x): pass,
,那么这个函数本身就是一个对象。
每个对象都有一个类型。但什么是类型?没错——甚至 类型本身 也是类型为 type
.
的对象
issubclass(type, object) # True
issubclass(object, type) # False
根据定义,每个 class 都是 object
的子 class。 object
class 不是任何东西的子class;它是所有 "objecthood" 的根源。因此 isinstance(o, object)
总是 returns True
.
type(type) is type # True
type(object) is type # True
我们知道 python 中的所有内容都是 object
的实例。但是 object
class 本身呢?也是一个对象。什么样的对象? object
是一种类型,就像 int
、str
或 function
一样。因此 object
的类型是 type
。但是,object
class 的任何 实例 都不是类型,而仅仅是一个对象:
type(object()) is object # True
综上所述,万物皆对象,甚至是其他对象的类型。
给non-answer一个"which comes first"的问题,其实没关系;这些东西无论如何都是抽象的,所以你可以用你想要定义的任何语义来创建一种语言,而且 "cycles".
没有错
为了给出更具体的答案,如果您对实现感兴趣,它看起来像 c-level PyObject
s(变成 object
)中的 typedef source code for CPython here,并与同一文件中 PyTypeObject
的 typedef 进行比较。
编辑:另一个答案更好地解释了 CPython 实现。
从语言语义的角度来看,type
和 object
都存在,从程序开始的那一刻起就完全初始化了。无论实现如何使事情进入该状态,都不必遵循实现允许你做的规则。
从 CPython 实现的角度来看,type
和 object
都是在 C 级别静态分配的,并且都不是首先创建的。您可以在 Objects/typeobject.c
中看到变量定义。 Here's object
:
PyTypeObject PyBaseObject_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"object", /* tp_name */
sizeof(PyObject), /* tp_basicsize */
0, /* tp_itemsize */
object_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_reserved */
object_repr, /* tp_repr */
...
};
PyTypeObject PyType_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"type", /* tp_name */
sizeof(PyHeapTypeObject), /* tp_basicsize */
sizeof(PyMemberDef), /* tp_itemsize */
(destructor)type_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_reserved */
(reprfunc)type_repr, /* tp_repr */
...
};
当解释器初始化开始时,type
和object
都处于half-initialized状态,PyType_Ready
函数负责完成它们的初始化。类型指针在变量定义中设置,但是设置超类指针是 PyType_Ready
工作的一部分,并且 PyType_Ready
需要处理大量其他初始化 - 例如,类型不还没有__dict__
。
顺便说一下,使用一些奇怪的元数据类 以及 Python 允许您在 user-defined 类、we can set up our own classes A
和 B
其中 B
是 A
的子类并且 A
和 B
都是 B
的实例,很像 object
和 type
的情况。这与 object
和 type
的实际创建方式完全不同,但是:
class DummyMeta(type):
pass
class A(type, metaclass=DummyMeta):
pass
class B(A):
pass
B.__class__ = B
A.__class__ = B
print(isinstance(A, B))
print(isinstance(B, B))
print(issubclass(B, A))
输出:
True
True
True
我记得学过 type
是它自己的实例,所有新式 classes 都继承自 object
,所以我开始胡闹:
issubclass(type, object) # True
issubclass(object, type) # False
# issubclass(cls, cls) is always True
type(type) is type # True
type(object) is type # True
总而言之,type
与任何新样式 class 一样是 object
的子 class,并且与任何 class 一样, type
和 object
都是 type
的实例。这是一张方便的图片:
在此声明我不是程序员,对 Python 的基本机制知之甚少,所以如果我听起来很蠢,请多多包涵。通常必须在其实例之前创建 class。然而,superclass 通常必须在它的 subclass 之前创建。将这些通用的 Python 规则应用于 type
和 object
会产生明显的先有鸡还是先有蛋的悖论。
那么这些 class 中哪些是先制作的?我还怀疑因为这些 classes 是用低级语言实现的,所以它们不必遵循 Python 规则。
在Python中,一切皆对象:
7
是类型int
的对象。'foo'
是str
类型的对象。None
是NoneType
类型的对象。- 如果你定义了一个class
class Foo: pass
,那么Foo
就是一个class
类型的对象。您从 class 构造的任何对象Foo()
都是类型Foo
的对象。 - 如果你将一个函数定义为
def f(x): pass,
,那么这个函数本身就是一个对象。
每个对象都有一个类型。但什么是类型?没错——甚至 类型本身 也是类型为 type
.
issubclass(type, object) # True
issubclass(object, type) # False
根据定义,每个 class 都是 object
的子 class。 object
class 不是任何东西的子class;它是所有 "objecthood" 的根源。因此 isinstance(o, object)
总是 returns True
.
type(type) is type # True
type(object) is type # True
我们知道 python 中的所有内容都是 object
的实例。但是 object
class 本身呢?也是一个对象。什么样的对象? object
是一种类型,就像 int
、str
或 function
一样。因此 object
的类型是 type
。但是,object
class 的任何 实例 都不是类型,而仅仅是一个对象:
type(object()) is object # True
综上所述,万物皆对象,甚至是其他对象的类型。
给non-answer一个"which comes first"的问题,其实没关系;这些东西无论如何都是抽象的,所以你可以用你想要定义的任何语义来创建一种语言,而且 "cycles".
没有错为了给出更具体的答案,如果您对实现感兴趣,它看起来像 c-level PyObject
s(变成 object
)中的 typedef source code for CPython here,并与同一文件中 PyTypeObject
的 typedef 进行比较。
编辑:另一个答案更好地解释了 CPython 实现。
从语言语义的角度来看,type
和 object
都存在,从程序开始的那一刻起就完全初始化了。无论实现如何使事情进入该状态,都不必遵循实现允许你做的规则。
从 CPython 实现的角度来看,type
和 object
都是在 C 级别静态分配的,并且都不是首先创建的。您可以在 Objects/typeobject.c
中看到变量定义。 Here's object
:
PyTypeObject PyBaseObject_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"object", /* tp_name */
sizeof(PyObject), /* tp_basicsize */
0, /* tp_itemsize */
object_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_reserved */
object_repr, /* tp_repr */
...
};
PyTypeObject PyType_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"type", /* tp_name */
sizeof(PyHeapTypeObject), /* tp_basicsize */
sizeof(PyMemberDef), /* tp_itemsize */
(destructor)type_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_reserved */
(reprfunc)type_repr, /* tp_repr */
...
};
当解释器初始化开始时,type
和object
都处于half-initialized状态,PyType_Ready
函数负责完成它们的初始化。类型指针在变量定义中设置,但是设置超类指针是 PyType_Ready
工作的一部分,并且 PyType_Ready
需要处理大量其他初始化 - 例如,类型不还没有__dict__
。
顺便说一下,使用一些奇怪的元数据类 以及 Python 允许您在 user-defined 类、we can set up our own classes A
和 B
其中 B
是 A
的子类并且 A
和 B
都是 B
的实例,很像 object
和 type
的情况。这与 object
和 type
的实际创建方式完全不同,但是:
class DummyMeta(type):
pass
class A(type, metaclass=DummyMeta):
pass
class B(A):
pass
B.__class__ = B
A.__class__ = B
print(isinstance(A, B))
print(isinstance(B, B))
print(issubclass(B, A))
输出:
True
True
True