python - Python 中类型和对象的先有鸡还是先有蛋悖论

标签 python object types instance subclass

我记得了解到 type 是它自己的实例,并且所有新式类都继承自 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 与任何新式类一样,都是 object 的子类,并且与任何类一样,都是 type > 和 objecttype 的实例。这是一张方便的图片:

Picture of relationship between type and object in Python

这里有一个重要的免责声明,我不是程序员,对 Python 的底层机制知之甚少,所以如果我听起来很愚蠢,请耐心等待。通常,必须在实例之前创建类。然而,父类(super class)通常必须在其子类之前创建。将这些通用 Python 规则应用于 typeobject 会产生明显的先有鸡还是先有蛋的悖论。

那么这些类中哪一个是首先创建的呢?我还怀疑,因为这些类是用较低级语言实现的,所以它们不必遵循 Python 规则。

最佳答案

从语言语义的角度来看,从程序开始的那一刻起,typeobject 就存在并完全初始化。无论实现做什么来使事情进入该状态,都不必遵循实现允许您执行的规则。

从 CPython 实现的角度来看,typeobject 都是在 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 */
    ...
};

here's type :

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 */
    ...
};

当解释器初始化开始时,typeobject都处于半初始化状态,PyType_Ready函数负责完成它们的初始化初始化。类型指针在变量定义中设置,但设置父类(super class)指针是 PyType_Ready 工作的一部分,并且许多其他初始化需要由 PyType_Ready 处理 -例如,这些类型还没有 __dict__

顺便说一句,使用一些奇怪的元类,并且 Python 允许您在用户定义类的实例上重新分配 __class__we can set up our own classes AB,其中 BA 的子类,并且 ABB 的实例,与 objecttype 的情况非常相似。但这与 objecttype 的实际创建方式完全不同:

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

关于python - Python 中类型和对象的先有鸡还是先有蛋悖论,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56502581/

相关文章:

python - 将行中的元组转换为 Dataframe 中的新列,必须使用 pandas 0.21

javascript - 如何制作多个嵌套对象的数组?

C# - 按 List<T> 中对象的属性排序

python - 如何将 IP 地址列表绘制为事件或非事件状态并保存到文本文件

python - 如何通过在单个单元格中删除 NaN 来调整数据框的大小?

python - tail 和 less 命令不能实时监控文件

javascript - 如何修复 'Objects are not valid as a React child (found: object with keys )'

c++ - 如何确保数据类型与 C++ 中需要的一样大

c++ - 根据大小扣除类型 C++

c++ - !expected type-specifier before ‘=’ token