公用对象结构体¶
大量的结构体被用于定义Python的对象类型。这一节描述了这些的结构体和它们的使用方法。
基本的对象类型和宏¶
所有的 Python 对象都在对象的内存表示的开始部分共享少量的字段。 这些字段用 PyObject 或 PyVarObject 类型来表示,这些类型又由一些宏定义,这些宏也直接或间接地用于所有其他 Python 对象的定义。
- 
type PyObject¶
-  Part of the Limited API. (Only some members are part of the stable ABI.)所有对象类型都是此类型的扩展。 这是一个包含了 Python 将对象的指针当作对象来处理所需的信息的类型。 在一个普通的“发行”编译版中,它只包含对象的引用计数和指向对应类型对象的指针。 没有什么对象被实际声明为 PyObject,但每个指向 Python 对象的指针都可以被转换为 PyObject*。 对成员的访问必须通过使用Py_REFCNT和Py_TYPE宏来完成。
- 
type PyVarObject¶
-  Part of the Limited API. (Only some members are part of the stable ABI.)这是一个添加了 ob_size字段的PyObject扩展。 它仅用于具有某些 长度 标记的对象。 此类型并不经常在 Python/C API 中出现。 对成员的访问必须通过使用Py_REFCNT,Py_TYPE和Py_SIZE宏来完成。
- 
PyObject_HEAD¶
- 这是一个在声明代表无可变长度对象的新类型时所使用的宏。 PyObject_HEAD 宏被扩展为: - PyObject ob_base; - 参见上面 - PyObject的文档。
- 
PyObject_VAR_HEAD¶
- 这是一个在声明代表每个实例具有可变长度的对象时所使用的宏。 PyObject_VAR_HEAD 宏被扩展为: - PyVarObject ob_base; - 参见上面 - PyVarObject的文档。
- 
int Py_Is(PyObject *x, PyObject *y)¶
-  Part of the Stable ABI since version 3.10.测试 x 是否为 y 对象,与 Python 中的 x is y相同。3.10 新版功能. 
- 
int Py_IsNone(PyObject *x)¶
-  Part of the Stable ABI since version 3.10.测试一个对象是否为 None单例,与 Python 中的x is None相同。3.10 新版功能. 
- 
int Py_IsTrue(PyObject *x)¶
-  Part of the Stable ABI since version 3.10.测试一个对象是否为 True单例,与 Python 中的x is True相同。3.10 新版功能. 
- 
int Py_IsFalse(PyObject *x)¶
-  Part of the Stable ABI since version 3.10.测试一个对象是否为 False单例,与 Python 中的x is False相同。3.10 新版功能. 
- 
PyTypeObject *Py_TYPE(PyObject *o)¶
- 获取 Python 对象 o 的类型。 - 返回一个 borrowed reference。 - 使用 - Py_SET_TYPE()函数来设置一个对象类型。
- 
int Py_IS_TYPE(PyObject *o, PyTypeObject *type)¶
- 如果对象 o 的类型为 type 则返回非零值。 否则返回零。 等价于: - Py_TYPE(o) == type。- 3.9 新版功能. 
- 
void Py_SET_TYPE(PyObject *o, PyTypeObject *type)¶
- 将对象 o 的类型设为 type。 - 3.9 新版功能. 
- 
Py_ssize_t Py_REFCNT(PyObject *o)¶
- 获取 Python 对象 o 的引用计数。 - 使用 - Py_SET_REFCNT()函数来设置一个对象引用计数。- 在 3.11 版更改: 形参类型不再是 const PyObject*。 - 在 3.10 版更改: - Py_REFCNT()被改为内联的静态函数。
- 
void Py_SET_REFCNT(PyObject *o, Py_ssize_t refcnt)¶
- 将对象 o 的引用计数器设为 refcnt。 - 3.9 新版功能. 
- 
Py_ssize_t Py_SIZE(PyVarObject *o)¶
- 获取 Python 对象 o 的大小。 - 使用 - Py_SET_SIZE()函数来设置一个对象大小。- 在 3.11 版更改: - Py_SIZE()被改为一个内联静态函数。 形参类型不再是 const PyVarObject*。
- 
void Py_SET_SIZE(PyVarObject *o, Py_ssize_t size)¶
- 将对象 o 的大小设为 size。 - 3.9 新版功能. 
- 
PyVarObject_HEAD_INIT(type, size)¶
- 这是一个为新的 - PyVarObject类型扩展初始化值的宏,包括- ob_size字段。 该宏会扩展为:- _PyObject_EXTRA_INIT 1, type, size, 
实现函数和方法¶
- 
type PyCFunction¶
-  Part of the Stable ABI.用于在 C 中实现大多数 Python 可调用对象的函数类型。 该类型的函数接受两个 PyObject* 形参并返回一个这样的值。 如果返回值为 NULL,则将设置一个异常。 如果不为NULL,则返回值将被解读为 Python 中暴露的函数的返回值。 此函数必须返回一个新的引用。函数的签名为: PyObject *PyCFunction(PyObject *self, PyObject *args); 
- 
type PyCFunctionWithKeywords¶
-  Part of the Stable ABI.用于在 C 中实现具有 METH_VARARGS | METH_KEYWORDS 签名的 Python 可调用对象的函数类型。 函数的签名为: PyObject *PyCFunctionWithKeywords(PyObject *self, PyObject *args, PyObject *kwargs); 
- 
type _PyCFunctionFast¶
- 用于在 C 中实现具有 - METH_FASTCALL签名的 Python 可调用对象的函数类型。 函数的签名为:- PyObject *_PyCFunctionFast(PyObject *self, PyObject *const *args, Py_ssize_t nargs); 
- 
type _PyCFunctionFastWithKeywords¶
- 用于在 C 中实现具有 METH_FASTCALL | METH_KEYWORDS 签名的 Python 可调用对象的函数类型。 函数的签名为: - PyObject *_PyCFunctionFastWithKeywords(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames); 
- 
type PyCMethod¶
- 用于在 C 中实现具有 METH_METHOD | METH_FASTCALL | METH_KEYWORDS 签名的 Python 可调用对象的函数类型。 函数的签名为: - PyObject *PyCMethod(PyObject *self, PyTypeObject *defining_class, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) - 3.9 新版功能. 
- 
type PyMethodDef¶
-  Part of the Stable ABI (including all members).用于描述一个扩展类型的方法的结构体。 该结构体有四个字段: - 
const char *ml_name¶
- 方法的名称。 
 - 
PyCFunction ml_meth¶
- 指向 C 语言实现的指针。 
 - 
int ml_flags¶
- 指明调用应当如何构建的旗标位。 
 - 
const char *ml_doc¶
- 指向文档字符串的内容。 
 
- 
const char *ml_name¶
ml_meth 是一个 C 函数指针。 该函数可以为不同类型,但它们将总是返回 PyObject*。 如果该函数不属于 PyCFunction,则编译器将要求在方法表中进行转换。 尽管 PyCFunction 将第一个参数定义为 PyObject*,但该方法的实现使用 self 对象的特定 C 类型也很常见。
ml_flags 字段是可以包含以下旗标的位字段。 每个旗标表示一个调用惯例或绑定惯例。
调用惯例有如下这些:
- 
METH_VARARGS¶
- 这是典型的调用惯例,其中方法的类型为 - PyCFunction。 该函数接受两个 PyObject* 值。 第一个是用于方法的 self 对象;对于模块函数,它将为模块对象。 第二个形参 (常被命名为 args) 是一个代表所有参数的元组对象。 该形参通常是使用- PyArg_ParseTuple()或- PyArg_UnpackTuple()来处理的。
- 
METH_KEYWORDS¶
- 只能用于同其他旗标形成特定的组合: METH_VARARGS | METH_KEYWORDS, METH_FASTCALL | METH_KEYWORDS 和 METH_METHOD | METH_FASTCALL | METH_KEYWORDS。 
- METH_VARARGS | METH_KEYWORDS
- 带有这些旗标的方法必须为 - PyCFunctionWithKeywords类型。 该函数接受三个形参: self, args, kwargs 其中 kwargs 是一个包含所有关键字参数的字典或者如果没有关键字参数则可以为- NULL。 这些形参通常是使用- PyArg_ParseTupleAndKeywords()来处理的。
- 
METH_FASTCALL¶
- 快速调用惯例仅支持位置参数。 这些方法的类型为 - _PyCFunctionFast。 第一个形参为 self,第二个形参是由表示参数的 PyObject* 值组成的数组而第三个形参是参数的数量(数组的长度)。- 3.7 新版功能. - 在 3.10 版更改: - METH_FASTCALL现在是 稳定 ABI 的一部分。
- METH_FASTCALL | METH_KEYWORDS
- METH_FASTCALL的扩展也支持关键字参数,它使用类型为- _PyCFunctionFastWithKeywords的方法。 关键字参数的传递方式与 vectorcall 协议 中的相同:还存在额外的第四个 PyObject* 参数,它是一个代表关键字参数名称(它将保证为字符串)的元组,或者如果没有关键字则可以为- NULL。 关键字参数的值存放在 args 数组中,在位置参数之后。- 3.7 新版功能. 
- 
METH_METHOD¶
- 只能与其他旗标组合使用: METH_METHOD | METH_FASTCALL | METH_KEYWORDS。 
- METH_METHOD | METH_FASTCALL | METH_KEYWORDS
- METH_FASTCALL | METH_KEYWORDS 的扩展支持 定义式类,也就是包含相应方法的类。 定义式类可以是 - Py_TYPE(self)的超类。- 该方法必须为 - PyCMethod类型,与在- self之后添加了- defining_class参数的- METH_FASTCALL | METH_KEYWORDS一样。- 3.9 新版功能. 
- 
METH_NOARGS¶
- 如果通过 - METH_NOARGS旗标列出了参数则没有形参的方法无需检查是否给出了参数。 它们必须为- PyCFunction类型。 第一个形参通常被命名为 self 并将持有对模块或对象实例的引用。 在所有情况下第二个形参都将为- NULL。- 该函数必须有 2 个形参。 由于第二个形参不会被使用, - Py_UNUSED可以被用来防止编译器警告。
- 
METH_O¶
- 具有一个单独对象参数的方法可使用 - METH_O旗标列出,而不必发起调用- PyArg_ParseTuple()并附带- "O"参数。 它们的类型为- PyCFunction,带有 self 形参,以及代表该单独参数的 PyObject* 形参。
这两个常量不是被用来指明调用惯例而是在配合类方法使用时指明绑定。 它们不会被用于在模块上定义的函数。 对于任何给定方法这些旗标最多只会设置其中一个。
- 
METH_CLASS¶
- 该方法将接受类型对象而不是类型的实例作为第一个形参。 它会被用于创建 类方法,类似于使用 - classmethod()内置函数所创建的结果。
- 
METH_STATIC¶
- 该方法将接受 - NULL而不是类型的实例作为第一个形参。 它会被用于创建 静态方法,类似于使用- staticmethod()内置函数所创建的结果。
另一个常量控制方法是否将被载入来替代具有相同方法名的另一个定义。
- 
METH_COEXIST¶
- 该方法将被加载以替代现有的定义。 如果没有 METH_COEXIST,默认将跳过重复的定义。 由于槽位包装器会在方法表之前被加载,例如 当存在 sq_contains 槽位时,将会生成一个名为 - __contains__()的已包装方法并阻止加载同名的相应 PyCFunction。 如果定义了此旗标,PyCFunction 将被加载以替代此包装器对象并与槽位共存。 因为对 PyCFunction 的调用相比对包装器对象调用更为优化所以这是很有帮助的。
访问扩展类型的属性¶
- 
type PyMemberDef¶
-  Part of the Stable ABI (including all members).描述与某个 C 结构体成员相对应的类型的属性的结构体。 它的字段有: 域 C 类型 含意 nameconst char * 成员名称 typeint C 结构体中成员的类型 offsetPy_ssize_t 成员在类型的对象结构体中所在位置的以字节表示的偏移量 flagsint 指明字段是否应为只读或可写的旗标位 docconst char * 指向文档字符串的内容 type可以是与各种 C 类型相对应的许多T_宏中的一个。 当在 Python 中访问该成员时,它将被转换为等价的 Python 类型。宏名称 C 类型 T_SHORT short T_INT int T_LONG 长整型 T_FLOAT float T_DOUBLE double T_STRING const char * T_OBJECT PyObject * T_OBJECT_EX PyObject * T_CHAR char T_BYTE char T_UBYTE unsigned char T_UINT unsigned int T_USHORT unsigned short T_ULONG unsigned long T_BOOL char T_LONGLONG long long T_ULONGLONG unsigned long long T_PYSSIZET Py_ssize_t T_OBJECT和T_OBJECT_EX的区别在于T_OBJECT返回None表示其成员为NULL并且T_OBJECT_EX引发了AttributeError。 请尝试使用T_OBJECT_EX取代T_OBJECT因为T_OBJECT_EX处理在属性上使用del语句比T_OBJECT更正确。flags可以为0表示读写访问或READONLY表示只读访问。 使用T_STRING作为type表示READONLY。T_STRING数据将被解读为 UTF-8 编码格式。 只有T_OBJECT和T_OBJECT_EX成员可以被删除。 (它们会被设为NULL)。堆分配类型 (使用 PyType_FromSpec()或类似函数创建),PyMemberDef可以包含特殊成员__dictoffset__,__weaklistoffset__和__vectorcalloffset__的定义,对应类型对象中的tp_dictoffset,tp_weaklistoffset和tp_vectorcall_offset。 它们必须使用T_PYSSIZET和READONLY来定义,例如:static PyMemberDef spam_type_members[] = { {"__dictoffset__", T_PYSSIZET, offsetof(Spam_object, dict), READONLY}, {NULL} /* Sentinel */ }; 
- 
PyObject *PyMember_GetOne(const char *obj_addr, struct PyMemberDef *m)¶
- 获取属于地址Get an attribute belonging to the object at address obj_addr 上的对象的某个属性。 该属性是以 - PyMemberDefm 来描述的。 出错时返回- NULL。
- 
int PyMember_SetOne(char *obj_addr, struct PyMemberDef *m, PyObject *o)¶
- 将属于位于地址 obj_addr 的对象的属性设置到对象 o。 要设置的属性由 - PyMemberDefm 描述。 成功时返回- 0而失败时返回负值。
- 
type PyGetSetDef¶
-  Part of the Stable ABI (including all members).用于定义针对某个类型的特征属性式的访问的结构体。 另请参阅 PyTypeObject.tp_getset槽位的描述。域 C 类型 含意 name const char * 属性名称 get getter 用于获取属性的 C 函数 set setter 用于设置或删除属性的可选 C 函数,如果省略则属性将为只读 doc const char * 可选的文档字符串 closure void * 可选的函数指针,为 getter 和 setter 提供附加数据 get函数接受一个 PyObject* 形参 (实例) 和一个函数指针 (关联的closure):typedef PyObject *(*getter)(PyObject *, void *); 它应当在成功时返回一个新的引用或在失败时返回 NULL并设置异常。set函数接受两个 PyObject* 形参 (实例和要设置的值) 和一个函数指针 (关联的closure):typedef int (*setter)(PyObject *, PyObject *, void *); 对于属性要被删除的情况第二个形参应为 NULL。 成功时应返回0或在失败时返回-1并设置异常。