类型对象¶
-
PyTypeObject PyType_Type¶
- 属于 稳定 ABI.
这是属于 type 对象的 type object,它在 Python 层面和
type
是相同的对象。
-
unsigned long PyType_GetFlags(PyTypeObject *type)¶
- 属于 稳定 ABI.
返回 type 的
tp_flags
成员。 此函数主要是配合Py_LIMITED_API
使用;单独的旗标位会确保在各个 Python 发布版之间保持稳定,但对tp_flags
本身的访问并不是 受限 API 的一部分。在 3.2 版本加入.
在 3.4 版本发生变更: 返回类型现在是
unsigned long
而不是long
。
-
PyObject *PyType_GetDict(PyTypeObject *type)¶
返回类型对象的内部命名空间,它在其他情况下只能通过只读代理 (
cls.__dict__
) 公开。 这可以代替直接访问tp_dict
的方式。 返回的字典必须当作是只读的。该函数用于特定的嵌入和语言绑定场景,在这些场景下需要直接访问该字典而间接访问(例如通过代理或
PyObject_GetAttr()
访问)并不足够。扩展模块在设置它们自己的类型时应当继续直接或间接地使用
tp_dict
。在 3.12 版本加入.
-
void PyType_Modified(PyTypeObject *type)¶
- 属于 稳定 ABI.
使该类型及其所有子类型的内部查找缓存失效。 此函数必须在对该类型的属性或基类进行任何手动修改之后调用。
-
int PyType_AddWatcher(PyType_WatchCallback callback)¶
注册 callback 作为类型监视器。 返回一个非负的整数 ID,它必须传给将来对
PyType_Watch()
的调用。 如果出错(例如没有足够的可用监视器 ID),则返回-1
并设置一个异常。在 3.12 版本加入.
-
int PyType_ClearWatcher(int watcher_id)¶
清除由 watcher_id (之前从
PyType_AddWatcher()
返回) 所标识的 watcher。 成功时返回0
,出错时(例如 watcher_id 未被注册)返回-1
。扩展在调用
PyType_ClearWatcher
时绝不能使用不是之前调用PyType_AddWatcher()
所返回的 watcher_id。在 3.12 版本加入.
-
int PyType_Watch(int watcher_id, PyObject *type)¶
将 type 标记为已监视。 每当
PyType_Modified()
报告 type 发生变化时PyType_AddWatcher()
赋予 watcher_id 的回调将被调用。 (如果在 type 的一系列连续修改之间没有调用_PyType_Lookup()
,则回调只能被调用一次;这是一个实现细节并可能发生变化)。扩展在调用
PyType_Watch
时绝不能使用不是之前调用PyType_AddWatcher()
所返回的 watcher_id。在 3.12 版本加入.
-
typedef int (*PyType_WatchCallback)(PyObject *type)¶
类型监视器回调函数的类型。
回调不可以修改 type 或是导致
PyType_Modified()
在 type 或其 MRO 中的任何类型上被调用;违反此规则可能导致无限递归。在 3.12 版本加入.
-
int PyType_HasFeature(PyTypeObject *o, int feature)¶
如果类型对象 o 设置了特性 feature 则返回非零值。 类型特性是用单个比特位旗标来表示的。
-
int PyType_IS_GC(PyTypeObject *o)¶
如果类型对象包括了对循环检测器的支持则返回真值;这将测试类型旗标
Py_TPFLAGS_HAVE_GC
。
-
int PyType_IsSubtype(PyTypeObject *a, PyTypeObject *b)¶
- 属于 稳定 ABI.
如果 a 是 b 的子类型则返回真值。
此函数只检查实际的子类型,这意味着
__subclasscheck__()
不会在 b 上被调用。 请调用PyObject_IsSubclass()
来执行与issubclass()
所做的相同检查。
-
PyObject *PyType_GenericAlloc(PyTypeObject *type, Py_ssize_t nitems)¶
- 返回值:新的引用。 属于 稳定 ABI.
类型对象的
tp_alloc
槽位的通用处理句柄。 请使用 Python 的默认内存分配机制来分配一个新的实例并将其所有内容初始化为NULL
。
-
PyObject *PyType_GenericNew(PyTypeObject *type, PyObject *args, PyObject *kwds)¶
- 返回值:新的引用。 属于 稳定 ABI.
-
int PyType_Ready(PyTypeObject *type)¶
- 属于 稳定 ABI.
最终化一个类型对象。 这应当在所有类型对象上调用以完成它们的初始化。 此函数会负责从一个类型的基类添加被继承的槽位。 成功时返回
0
,或是在出错时返回-1
并设置一个异常。备注
如果某些基类实现了 GC 协议并且所提供的类型的旗标中未包括
Py_TPFLAGS_HAVE_GC
,则将自动从其父类实现 GC 协议。 相反地,如果被创建的类型的旗标中确实包含Py_TPFLAGS_HAVE_GC
则它 必须 自己实现 GC 协议,至少要实现tp_traverse
句柄。
-
PyObject *PyType_GetName(PyTypeObject *type)¶
- 返回值:新的引用。 属于 稳定 ABI 自 3.11 版开始.
返回类型名称。 等同于获取类型的
__name__
属性。在 3.11 版本加入.
-
PyObject *PyType_GetQualName(PyTypeObject *type)¶
- 返回值:新的引用。 属于 稳定 ABI 自 3.11 版开始.
返回类型的限定名称。 等同于获取类型的
__qualname__
属性。在 3.11 版本加入.
-
void *PyType_GetSlot(PyTypeObject *type, int slot)¶
- 属于 稳定 ABI 自 3.4 版开始.
返回存储在给定槽位中的函数指针。 如果结果为
NULL
,则表示或者该槽位为NULL
,或者该函数调用传入了无效的形参。 调用方通常要将结果指针转换到适当的函数类型。请参阅
PyType_Slot.slot
查看可用的 slot 参数值。在 3.4 版本加入.
在 3.10 版本发生变更:
PyType_GetSlot()
现在可以接受所有类型。 在此之前,它被限制为 堆类型。
-
PyObject *PyType_GetModule(PyTypeObject *type)¶
- 属于 稳定 ABI 自 3.10 版开始.
返回当使用
PyType_FromModuleAndSpec()
创建类型时关联到给定类型的模块对象。如果没有关联到给定类型的模块,则设置
TypeError
并返回NULL
。此函数通常被用于获取方法定义所在的模块。 请注意在这样的方法中,
PyType_GetModule(Py_TYPE(self))
可能不会返回预期的结果。Py_TYPE(self)
可以是目标类的一个 子类,而子类并不一定是在与其超类相同的模块中定义的。 请参阅PyCMethod
了解如何获取方法定义所在的类。 请参阅PyType_GetModuleByDef()
了解有关无法使用PyCMethod
的情况。在 3.9 版本加入.
-
void *PyType_GetModuleState(PyTypeObject *type)¶
- 属于 稳定 ABI 自 3.10 版开始.
返回关联到给定类型的模块对象的状态。 这是一个在
PyType_GetModule()
的结果上调用PyModule_GetState()
的快捷方式。如果没有关联到给定类型的模块,则设置
TypeError
并返回NULL
。如果 type 有关联的模块但其状态为
NULL
,则返回NULL
且不设置异常。在 3.9 版本加入.
-
PyObject *PyType_GetModuleByDef(PyTypeObject *type, struct PyModuleDef *def)¶
找到所属模块基于给定的
PyModuleDef
def 创建的第一个上级类,并返回该模块。如果未找到模块,则会引发
TypeError
并返回NULL
。此函数预期会与
PyModule_GetState()
一起使用以便从槽位方法 (如tp_init
或nb_add
) 及其他定义方法的类无法使用PyCMethod
调用惯例来传递的场合获取模块状态。在 3.11 版本加入.
-
int PyUnstable_Type_AssignVersionTag(PyTypeObject *type)¶
- 这是 不稳定 API。 它可能在微发布版中不带警告地改变。
尝试为给定的类型设置一个版本标签。
如果类型已有合法的版本标签或已设置了新的版本标签则返回 1,或者如果无法设置新的标签则返回 0。
在 3.12 版本加入.
创建堆分配类型¶
下列函数和结构体可被用来创建 堆类型。
-
PyObject *PyType_FromMetaclass(PyTypeObject *metaclass, PyObject *module, PyType_Spec *spec, PyObject *bases)¶
- 属于 稳定 ABI 自 3.12 版开始.
根据 spec (参见
Py_TPFLAGS_HEAPTYPE
) 创建并返回一个 堆类型。元类 metaclass 用于构建结果类型对象。 当 metaclass 为
NULL
时,元类将派生自 bases (或者如果 bases 为NULL
则派生自 Py_tp_base[s] 槽位,见下文)。不支持重写
tp_new
的元类,除非tp_new
为NULL
。 (为了向下兼容,其他PyType_From*
函数允许这样的元类。 它们将忽略tp_new
,可能导致不完整的初始化。 这样的元类已被弃用并在 Python 3.14+ 中停止支持。)bases 参数可被用来指定基类;它可以是单个类或由多个类组成的元组。 如果 bases 为
NULL
,则会改用 Py_tp_bases 槽位。 如果该槽位也为NULL
,则会改用 Py_tp_base 槽位。 如果该槽位同样为NULL
,则新类型将派生自object
。module 参数可被用来记录新类定义所在的模块。 它必须是一个模块对象或为
NULL
。 如果不为NULL
,则该模块会被关联到新类型并且可在之后通过PyType_GetModule()
来获取。 这个关联模块不可被子类继承;它必须为每个类单独指定。此函数会在新类型上调用
PyType_Ready()
。请注意此函数 不能 完全匹配调用
type()
或使用class
语句的行为。 对于用户提供的类型或元类,推荐 调用type
(或元类) 而不是PyType_From*
函数。 特别地:__new__()
不会在新类上被调用 (它必须被设为type.__new__
)。__init__()
不会在新类上被调用。__init_subclass__()
不会在任何基类上调用。__set_name__()
不会在新的描述器上调用。
在 3.12 版本加入.
-
PyObject *PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases)¶
- 返回值:新的引用。 属于 稳定 ABI 自 3.10 版开始.
等价于
PyType_FromMetaclass(NULL, module, spec, bases)
。在 3.9 版本加入.
在 3.10 版本发生变更: 此函数现在接受一个单独类作为 bases 参数并接受
NULL
作为tp_doc
槽位。
-
PyObject *PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases)¶
- 返回值:新的引用。 属于 稳定 ABI 自 3.3 版开始.
等价于
PyType_FromMetaclass(NULL, NULL, spec, bases)
。在 3.3 版本加入.
-
PyObject *PyType_FromSpec(PyType_Spec *spec)¶
- 返回值:新的引用。 属于 稳定 ABI.
等价于
PyType_FromMetaclass(NULL, NULL, spec, NULL)
。
-
type PyType_Spec¶
- 属于 稳定 ABI (包括所有成员).
定义一个类型的行为的结构体。
-
const char *name¶
类型的名称,用来设置
PyTypeObject.tp_name
。
-
int basicsize¶
如果为正数,则以字节为单位指定实例的大小。 它用于设置
PyTypeObject.tp_basicsize
。如果为零,则指定应当继承
tp_basicsize
。如果为负数,则以其绝对值指定该类的实例在超类的 基础之上 还需要多少空间。 使用
PyObject_GetTypeData()
来获取通过此方式保留的子类专属内存的指针。在 3.12 版本发生变更: 在之前版本中,此字段不能为负数。
-
int itemsize¶
可变大小类型中一个元素的大小,以字节为单位。 用于设置
PyTypeObject.tp_itemsize
。 注意事项请参阅tp_itemsize
文档。如果为零,则会继承
tp_itemsize
。 扩展任意可变大小的类是很危险的,因为某些类型使用固定偏移量来标识可变大小的内存,这样就会与子类使用的固定大小的内存相重叠。 为了防止出错,只有在以下情况下才可以继承itemsize
:基类不是可变大小的 (即其
tp_itemsize
)。所请求的
PyType_Spec.basicsize
为正值,表明基类的内存布局是已知的。所请求的
PyType_Spec.basicsize
为零,表明子类不会直接访问实例的内存。具有
Py_TPFLAGS_ITEMS_AT_END
旗标。
-
unsigned int flags¶
类型旗标,用来设置
PyTypeObject.tp_flags
。如果未设置
Py_TPFLAGS_HEAPTYPE
旗标,则PyType_FromSpecWithBases()
会自动设置它。
-
PyType_Slot *slots¶
PyType_Slot
结构体的数组。 以特殊槽位值{0, NULL}
来结束。每个槽位 ID 应当只被指定一次。
-
const char *name¶
-
type PyType_Slot¶
- 属于 稳定 ABI (包括所有成员).
定义一个类型的可选功能的结构体,包含一个槽位 ID 和一个值指针。
-
int slot¶
槽位 ID。
槽位 ID 的类名像是结构体
PyTypeObject
,PyNumberMethods
,PySequenceMethods
,PyMappingMethods
和PyAsyncMethods
的字段名附加一个Py_
前缀。 举例来说,使用:Py_tp_dealloc
设置PyTypeObject.tp_dealloc
Py_nb_add
设置PyNumberMethods.nb_add
Py_sq_length
设置PySequenceMethods.sq_length
下列 “offset” 字段不可使用
PyType_Slot
来设置:tp_weaklistoffset
(如果可能请改用Py_TPFLAGS_MANAGED_WEAKREF
)tp_dictoffset
(如果可能请改用Py_TPFLAGS_MANAGED_DICT
)tp_vectorcall_offset
(请使用 PyMemberDef 中的"__vectorcalloffset__"
)
如果无法转为
MANAGED
旗标 (例如,对于 vectorcall 或是为了支持早于 Python 3.12 的版本),请在Py_tp_members
中指定 offset。 详情参见 PyMemberDef documentation。以下字段在创建堆类型时完全不可设置:
tp_vectorcall
(请使用tp_new
和/或tp_init
)内部字段:
tp_dict
,tp_mro
,tp_cache
,tp_subclasses
和tp_weaklist
。
在某些平台上设置
Py_tp_bases
或Py_tp_base
可能会有问题。 为了避免问题,请改用PyType_FromSpecWithBases()
的 bases 参数。在 3.9 版本发生变更:
PyBufferProcs
中的槽位可能会在不受限 API 中被设置。在 3.11 版本发生变更: 现在
bf_getbuffer
和bf_releasebuffer
将在 受限 API 中可用。
-
void *pfunc¶
该槽位的预期值。 在大多数情况下,这将是一个指向函数的指针。
Py_tp_doc
以外的槽位均不可为NULL
。
-
int slot¶