公共对象结构

在Python的对象类型的定义中使用了大量结构。本节描述了这些结构及其使用方法.

所有Python对象最终在对象在内存中的表示开头共享少量字段。它们由PyObjectPyVarObject类型表示,它们又由一些宏的扩展定义,无论是直接还是间接地在所有其他Python对象的定义中使用.

PyObject
所有对象类型都是此类型的扩展名。这是一种包含Python将对象指针作为对象处理的信息的类型。在正常的“发布”版本中,它只包含对象的引用计数和指向相应类型对象的指针。实际上没有声明为PyObject,但每个Python对象都可以转换为PyObject*。访问主题必须使用宏Py_REFCNTPy_TYPE.
PyVarObject
这是PyObject添加ob_size字段。这仅适用于具有length概念的对象。此类型通常不会出现在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的文档.

Py_TYPE o
这个宏用于访问Python对象ob_type成员。它扩展为:

(((PyObject*)(o))->ob_type)
Py_REFCNT o
这个宏用来访问ob_refcntPythonobject的成员。它扩展为:

(((PyObject*)(o))->ob_refcnt)
Py_SIZE o
这个宏用于访问ob_size成员一个Python对象。它扩展为:

(((PyVarObject*)(o))->ob_size)
PyObject_HEAD_INIT type
这是一个宏,它扩展为新的PyObject类型。这个宏扩展为:

_PyObject_EXTRA_INIT
1, type,
PyVarObject_HEAD_INIT型号,尺寸
这是一个宏,它扩展为新的PyVarObjecttype,包括ob_size字段。这个宏扩展为:

_PyObject_EXTRA_INIT
1, type, size,
PyCFunction
用于实现C.Cunctions中大多数Python callables的函数类型需要两个PyObject*参数和returnone这样的值。如果返回值为NULL,则应设置例外。如果不 NULL,返回值被解释为Python中公开的函数的返回值。该功能必须返回一个新的参考.
PyCFunctionWithKeywords
用于在C中实现带有关键字参数的Python callables的函数类型:它们需要三个PyObject*参数并返回这样的值。见PyCFunction以上是returnvalue的含义.
PyMethodDef
用于描述扩展类型方法的结构。这个结构有四个字段:

字段 C类型 含义
ml_name const char * 方法的名称
ml_meth PyCFunction 指向Cimplementation的指针
ml_flags int 表示如何构造调用的标志位
ml_doc const char* 指向thedocstring的内容

ml_meth是一个C函数指针。函数可能是不同的类型,但它们总是返回PyObject*。如果功能不是PyCFunction,编译器将需要方法表中的强制转换。即使PyCFunction将第一个参数定义为PyObject*,方法实现通常使用self对象

ml_flagsfield是一个位域,可以包含以下标志。各个标志表示调用约定或绑定约定。在调用约定标志中,只有METH_VARARGSMETH_KEYWORDS可以合并。任何调用约定标志都可以与绑定标志组合.

METH_VARARGS
这是典型的调用约定,其中方法的类型为PyCFunction。功能要求两个PyObject*价值观。第一个是self方法的对象;对于模块功能,它是模块对象。第二个参数(通常称为args)是一个表示所有参数的元组对象。此参数通常使用PyArg_ParseTuple()PyArg_UnpackTuple().
METH_KEYWORDS
处理。带有这些标志的方法必须是PyCFunctionWithKeywords类型。函数需要三个参数:self, args,以及所有关键字参数的字典。标志必须与METH_VARARGS组合,参数通常用PyArg_ParseTupleAndKeywords().
METH_NOARGS
没有参数的方法不需要检查是否给出参数,如果它们与METH_NOARGS标志一起列出。它们需要是PyCFunction的类型。第一个参数通常命名为self并将保留对模块或对象实例的引用。在所有情况下,第二个参数都是NULL.
METH_O
带有单个对象参数的方法可以用METH_O标志,而不是用PyArg_ParseTuple()参数调用"O"。它们的类型为PyCFunction,带有self参数,并且PyObject*表示单个参数的参数.

这两个常量不用于表示调用约定,而是用于与类方法一起使用时的绑定。这些不能用于为模块定义的函数。对于任何给定的方法,最多可以设置其中一个标志.

METH_CLASS

该方法将作为第一个参数传递类型对象,而不是该类型的实例。这用于创建class methods,类似于使用classmethod() built-infunction.

METH_STATIC

该方法将作为第一个参数传递NULL而不是类型的实例。这用于创建static methods,类似于使用staticmethod()内置函数时创建的

另一个常量控制是否使用相同的方法名称加载方法来代替另一个定义.

METH_COEXIST
将加载该方法以代替现有定义。没有METH_COEXIST,默认是跳过重复的定义。由于在方法表之前加载了slotwrappers,例如sq_contains slot的存在会生成一个名为__contains__()并阻止加载具有相同名称的对应的PICFunction。定义了标志后,将加载PyCFunction代替包装器对象,并与该槽共存。这很有用,因为对PyCFunctions的调用优于包装器对象调用.
PyMemberDef
描述与Cstruct成员对应的类型的属性的结构。它的字段是:

字段 C类型 含义
name const char * 会员名称
type INT C struct
offset Py_ssize_t 中的成员类型,以body为对象的结构
flags int 标志位指示该字段是否应该是只读的
doc const char * 指向thedocstring的内容

type可以是其中之一T_对应于各种Ctypes的宏。当用Python访问该成员时,它将被转换为等价的Python类型.

Macro name C型
T_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 很长
T_ULONGLONG unsigned long很长
T_PYSSIZET Py_ssize_t

T_OBJECTT_OBJECT_EX不同之处T_OBJECT返回None如果会员是NULLT_OBJECT_EX举起AttributeError。尝试使用T_OBJECT_EX over T_OBJECT因为T_OBJECT_EX更正确地处理对该属性使用del语句T_OBJECT.

flags可以0用于写入和读取访问或READONLY仅用于读取访问。使用T_STRING表示type表示READONLY. T_STRING数据被解释为UTF-8.只有T_OBJECTT_OBJECT_EX成员可以被删除。(它们设置为NULL).

PyGetSetDef
用于为类型定义类属性访问的结构。另见PyTypeObject.tp_getset槽的描述

字段 C类型 含义
名称 const char * 属性名称
得到 getter C函数获取属性
设置 setter 可选C函数来设置或删除属性,如果省略则属性是只读
doc const char * 可选docstring
closure void * 可选函数指针,提供额外的数据遗忘和设置

get函数需要一个PyObject*参数(实例)和一个函数指针(关联的closure):

typedef PyObject *(*getter)(PyObject *, void *);

它应该返回一个成功的新引用或NULL并设置例外失败.

set函数需要两个PyObject*参数(实例和要设置的值)和函数指针(关联的closure):

typedef int (*setter)(PyObject *, PyObject *, void *);

如果要删除属性,则第二个参数NULL。应该在成功时返回0或者在失败时设置例外-1.