在CPython中,用C实现的类型是类型树的一部分

2020-12-25 00:36:58

从理论上讲,在Python中,所有类型都源自对象(它们是对象的直接或间接子类)。多年来,我一直相信(并书面认为)在实现级别上,对于用CPython用本机C代码编写的类型(Python的标准实现以及您可能正在使用的一种)而言,情况并非如此。用Cmight编写的类型的行为就好像它们是对象的后代一样,但是我认为它们的行为实际上是完全独立的,由C中的每个类型分别实现。感谢Python幕后#6:Python对象系统的工作原理,我发现我错了。

在CPython中,C级Python类型实际上不是对象的C级版本的子类,因为在这种情况下C当然没有类和子类。相反,您通常通过为其定义PyTypeObject结构来描述您的类型,并根据需要填写或不填写各种字段,包括基本类型的tp_base字段(如果您需要多个基本类型) ,则需要采用堆类型的备用路径)。当CPython需要对您的类型执行特殊方法或其他操作时,它将直接使用PyTypeObjectstructure上的字段(据我所知,它仅使用这些字段,没有回退)。从表面上看,tp_base字段本质上是装饰性的,仅在有人询问时才用于报告您声明的__base__。

但是,幕后隐藏了一些CPython魔术。为了实际使用PyTypeObject作为类型,必须注册它并通过调用PyType_Ready使其准备就绪。作为其一部分,PyType_Ready将使用您类型的tp_base来填充PyTypeObject的各个字段(如果您尚未这样做的话),这实际上意味着您的C级类型将从其基本类型继承这些字段(依此类推)一直到对象)。在C API的一部分中对此进行了概述,但是我当然不会自己阅读C API,因为我从来不需要使用它。Python对象系统的工作原理将详细介绍如何工作。很好奇,还有关于特殊方法也如何工作的详细信息(这比我所想的要有趣得多,我之前已经看过这方面)。

(repr()认为的' type'和' class'之间的区别有些随意;请参见边栏。用PyTypeObject定义的C级内容可能永远是考虑类型而不是类。)