类型对象

类型对象

Python 对象系统中最重要的一个结构体也许是定义新类型的结构体: PyTypeObject 结构体。 类型对象可以使用任何 PyObject_* 或 PyType_* 函数来处理,但并未提供大多数 Python 应用程序会感兴趣的东西。 这些对象是对象行为的基础,所以它们对解释器本身及任何实现新类型的扩展模块都非常重要。

与大多数标准类型相比,类型对象相当大。这么大的原因是每个类型对象存储了大量的值,大部分是C函数指针,每个指针实现了类型功能的一小部分。本节将详细描述类型对象的字段。这些字段将按照它们在结构中出现的顺序进行描述。

除了下面的快速参考, 例子 小节提供了快速了解 PyTypeObject 的含义和用法的例子。

快速参考

“tp 槽位”

PyTypeObject 槽位 [1] 类型 特殊方法/属性 信息 [2]
O T D I
<R> tp name const char __ name X
tp basicsize Py _ssize _t__ X
tp itemsize Py _ssize _t__
tp dealloc destructor X
tp vectorcall_offset Py_ssize_t
(tp_getattr) getattrfunc __getattribute, __getattr
(tp_setattr) setattrfunc __setattr, __delattr
tp_as_async PyAsyncMethods 子槽位
tp repr reprfunc repr X
tp _as _number__ PyNumberMethods __ 子槽位
tp_as_sequence PySequenceMethods 子槽位
tp _as _mapping__ PyMappingMethods __ 子槽位
tp hash hashfunc hash X
tp call ternaryfunc call
tp str reprfunc str X
tp getattro getattrofunc getattribute , getattr X
tp_setattro setattrofunc __setattr, __delattr X
tp_as_buffer PyBufferProcs
tp flags unsigned long X
tp doc const char __ doc X
tp traverse traverseproc
tp clear inquiry
tp richcompare richcmpfunc lt , le , eq , ne , gt , ge X
(tp weaklistoffset ) Py_ssize_t
tp_iter getiterfunc __iter
tp_iternext iternextfunc __next
tp_methods PyMethodDef [] X
tp_members PyMemberDef []
tp_getset PyGetSetDef [] X
tp_base PyTypeObject base
tp dict PyObject * dict
tp _descr _get__ descrgetfunc get
tp _descr _set__ descrsetfunc set , __delete_
(tp_dictoffset) Py_ssize_t
tp_init initproc __init X
tp_alloc allocfunc X
tp_new newfunc __new X
tp_free freefunc X
tp_is_gc inquiry
<tp_bases> PyObject * __bases
<tp_mro> PyObject * __mro
[tp_cache] PyObject __
[tp_subclasses] void __subclasses
[tp_weaklist] PyObject *
(tp_del) destructor
[tp_version_tag] unsigned int
tp_finalize destructor __del
tp_vectorcall vectorcallfunc
[tp_watched] unsigned char

[1]

() :括号中的插槽名称表示(实际上)已弃用。

< >: 尖括号内的名称在初始时应设为 NULL 并被视为是只读的。

[] : 方括号内的名称仅供内部使用。

< R> (作为前缀) 表示字段是必需的 (不能是 NULL)。

[2]

列:

“O” : 在 PyBaseObject_Type 上设置

“T” : 在 PyType_Type 上设置

“D” : 默认设置(如果方法槽被设置为NULL)

X - PyType_Ready 如其为 NULL 则设置该值
~ - PyType_Ready 始终设置该值 (它应当为 NULL)
? - PyType_Ready 根据其他槽位可能设置该值

另请参阅继承列 ("I")。

“I” : 继承

X - 如果使用 *NULL* 值定义则类型槽位将通过 *PyType_Ready* 继承
% - 子结构体的槽位是单独继承的
G - 已继承,但仅会与其他槽位相结合;参见槽位的说明
? - 较复杂;参见槽位的说明

注意,有些方法槽是通过普通属性查找链有效继承的。

子槽位

槽位 类型 特殊方法
am await unaryfunc await
am aiter unaryfunc aiter
am anext unaryfunc anext
am send sendfunc
nb add binaryfunc add radd
nb _inplace _add__ binaryfunc iadd
nb subtract binaryfunc sub rsub
nb _inplace _subtract__ binaryfunc isub
nb multiply binaryfunc mul rmul
nb _inplace _multiply__ binaryfunc imul
nb remainder binaryfunc mod rmod
nb _inplace _remainder__ binaryfunc imod
nb divmod binaryfunc divmod rdivmod
nb power ternaryfunc pow rpow
nb _inplace _power__ ternaryfunc ipow
nb negative unaryfunc neg
nb positive unaryfunc pos
nb absolute unaryfunc abs
nb bool inquiry bool
nb invert unaryfunc invert
nb lshift binaryfunc lshift rlshift
nb _inplace _lshift__ binaryfunc ilshift
nb rshift binaryfunc rshift rrshift
nb _inplace _rshift__ binaryfunc irshift
nb and binaryfunc and rand
nb _inplace _and__ binaryfunc iand
nb xor binaryfunc xor rxor
nb _inplace _xor__ binaryfunc ixor
nb or binaryfunc or ror
nb _inplace _or__ binaryfunc ior
nb int unaryfunc int
nb reserved void *
nb float unaryfunc __float_
nb_floor_divide binaryfunc __floordiv
nb_inplace_floor_divide binaryfunc __ifloordiv
nb_true_divide binaryfunc __truediv
nb_inplace_true_divide binaryfunc __itruediv
nb_index unaryfunc __index
nb_matrix_multiply binaryfunc __matmul __rmatmul
nb_inplace_matrix_multiply binaryfunc __imatmul
mp_length lenfunc __len
mp_subscript binaryfunc __getitem
mp_ass_subscript objobjargproc __setitem, __delitem
sq_length lenfunc __len
sq_concat binaryfunc __add
sq_repeat ssizeargfunc __mul
sq_item ssizeargfunc __getitem
sq_ass_item ssizeobjargproc __setitem __delitem
sq_contains objobjproc __contains
sq_inplace_concat binaryfunc __iadd
sq_inplace_repeat ssizeargfunc __imul
bf_getbuffer getbufferproc()
bf_releasebuffer releasebufferproc()

槽位 typedef

typedef 参数类型 返回类型
allocfunc PyTypeObject ___Py_ssize_t_ PyObject
destructor PyObject __ void
freefunc void void
traverseproc PyObject ___visitproc _void int
newfunc PyObject ___PyObject _PyObject __ PyObject
initproc PyObject ___PyObject _PyObject __ int
reprfunc PyObject PyObject __
getattrfunc PyObject const char __ PyObject
setattrfunc PyObject ___const char_PyObject __ int
getattrofunc PyObject PyObject __ PyObject
setattrofunc PyObject ___PyObject _PyObject __ int
descrgetfunc PyObject PyObject ___PyObject _ PyObject __
descrsetfunc PyObject PyObject ___PyObject _ int
hashfunc PyObject __ Py_hash_t
richcmpfunc PyObject PyObject ___int_ PyObject
getiterfunc PyObject __ PyObject
iternextfunc PyObject __ PyObject
lenfunc PyObject __ Py_ssize_t
getbufferproc PyObject Py_buffer ___int_ int
releasebufferproc PyObject Py_buffer __ void
inquiry PyObject int
unaryfunc PyObject __ PyObject
binaryfunc PyObject ___PyObject _ PyObject __
ternaryfunc PyObject PyObject ___PyObject _ PyObject __
ssizeargfunc PyObject Py_ssize_t PyObject __
ssizeobjargproc PyObject Py_ssize_tPyObject __ int
objobjproc PyObject PyObject __ int
objobjargproc PyObject PyObject ___PyObject _ int

请参阅 槽位类型 typedef 里有更多详细信息。

PyTypeObject 定义

PyTypeObject 的结构定义可以在 Include/object.h 中找到。 为了方便参考,此处复述了其中的定义:

typedef struct _typeobject {
    PyObject_VAR_HEAD
    const char *tp_name; /* 用于打印,格式为 "<module>.<name>" */
    Py_ssize_t tp_basicsize, tp_itemsize; /* 用于分配 */

    /* 用于实现标准操作的方法 */

    destructor tp_dealloc;
    Py_ssize_t tp_vectorcall_offset;
    getattrfunc tp_getattr;
    setattrfunc tp_setattr;
    PyAsyncMethods *tp_as_async; /* 原名为 tp_compare (Python 2)
                                    或 tp_reserved (Python 3) */
    reprfunc tp_repr;

    /* 用于标准类的方法集 */

    PyNumberMethods *tp_as_number;
    PySequenceMethods *tp_as_sequence;
    PyMappingMethods *tp_as_mapping;

    /* 更多标准操作(这些用于二进制兼容) */

    hashfunc tp_hash;
    ternaryfunc tp_call;
    reprfunc tp_str;
    getattrofunc tp_getattro;
    setattrofunc tp_setattro;

    /* 用于以输入/输出缓冲区方式访问对象的函数 */
    PyBufferProcs *tp_as_buffer;

    /* 用于定义可选/扩展特性是否存在的旗标 */
    unsigned long tp_flags;

    const char *tp_doc; /* 文档字符串 */

    /* 在 2.0 发布版中分配的含义 */
    /* 为所有可访问的对象调用函数 */
    traverseproc tp_traverse;

    /* 删除对所包含对象的引用 */
    inquiry tp_clear;

    /* 在 2.1 发布版中分配的含义 */
    /* 富比较操作 */
    richcmpfunc tp_richcompare;

    /* 弱引用的启用 */
    Py_ssize_t tp_weaklistoffset;

    /* 迭代器 */
    getiterfunc tp_iter;
    iternextfunc tp_iternext;

    /* 属性描述器和子类化内容 */
    struct PyMethodDef *tp_methods;
    struct PyMemberDef *tp_members;
    struct PyGetSetDef *tp_getset;
    // 堆类型的强引用,静态类型的借入引用
    struct _typeobject *tp_base;
    PyObject *tp_dict;
    descrgetfunc tp_descr_get;
    descrsetfunc tp_descr_set;
    Py_ssize_t tp_dictoffset;
    initproc tp_init;
    allocfunc tp_alloc;
    newfunc tp_new;
    freefunc tp_free; /* 低层级的释放内存例程 */
    inquiry tp_is_gc; /* For PyObject_IS_GC */
    PyObject *tp_bases;
    PyObject *tp_mro; /* 方法解析顺序 */
    PyObject *tp_cache;
    PyObject *tp_subclasses;
    PyObject *tp_weaklist;
    destructor tp_del;

    /* 类型属性缓存版本标签。 在 2.6 版中添加 */
    unsigned int tp_version_tag;

    destructor tp_finalize;
    vectorcallfunc tp_vectorcall;

    /* 类型监视器针对此类型的位设置 */
    unsigned char tp_watched;
} PyTypeObject;

PyObject 槽位

类型对象结构体扩展了 PyVarObject 结构体。 ob_size 字段用于动态类型(由 type_new() 创建,通常由 class 语句调用)。 请注意 PyType_Type (元类型)会初始化 tp_itemsize,这意味着它的实例(即类型对象) 必须 具有 ob_size 字段。

Py_ssize_t PyObject.ob_refcnt

属于稳定 ABI.

这是类型对象的引用计数,由 PyObject_HEAD_INIT 宏初始化为 1。 请注意对于 静态分配的类型对象,类型的实例(其 ob_type 指向该类型的对象) 不会被 计入引用。 但对于 动态分配的类型对象,实例 会被 计入引用。

继承:

子类型不继承此字段。

PyTypeObject *PyObject.ob_type

属于稳定 ABI.

这是类型的类型,换句话说就是元类型,它由宏 PyObject_HEAD_INIT 的参数来做初始化,它的值一般情况下是 &PyType_Type 。可是为了使动态可载入扩展模块至少在Windows上可用,编译器会报错这是一个不可用的初始化。因此按照惯例传递 NULL 给宏 PyObject_HEAD_INIT 并且在模块的初始化函数开始时候其他任何操作之前初始化这个字段。典型做法是这样的:

Foo_Type.ob_type = &PyType_Type;

这应当在创建类型的任何实例之前完成。 PyType_Ready() 会检查 ob_type 是否为 NULL,如果是,则将其初始化为基类的 ob_type 字段。 如果该字段为非零值则 PyType_Ready() 将不会更改它。

继承:

此字段会被子类型继承。

PyVarObject 槽位

Py_ssize_t PyVarObject.ob_size

属于稳定 ABI.

对于 静态分配的内存对象,它应该初始化为 0。对于 动态分配的类型对象,该字段具有特殊的内部含义。

继承:

子类型不继承此字段。

(本文超出站点单文档体积上限,已按小节截断)