Common Object Structures

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

所有Python对象最终在对象在内存中的表示的开始处共享少量字段。这些由PyObjectPyVarObject类型表示,这些类型又由一些宏的扩展定义,这些宏也是直接或间接在所有的定义中使用的其他Python对象。

PyObject

所有对象类型都是此类型的扩展。这是一个类型,它包含Python需要将指向对象的指针作为对象的信息。在正常的“释放”构建中,它只包含对象的引用计数和指向相应类型对象的指针。实际上没有声明为PyObject,但是每个指向Python对象的指针都可以转换为PyObject*必须使用宏Py_REFCNTPy_TYPE来访问成员。

PyVarObject

这是添加ob_size字段的PyObject的扩展。这仅用于具有长度的某些概念的对象。此类型通常不会出现在Python / C API中。必须使用宏Py_REFCNTPy_TYPEPy_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)

此宏用于访问Python对象的ob_refcnt成员。它扩展到:

(((PyObject*)(o))->ob_refcnt)
Py_SIZE(o)

此宏用于访问Python对象的ob_size成员。它扩展到:

(((PyVarObject*)(o))->ob_size)
PyObject_HEAD_INIT(type)

这是一个宏,扩展为新的PyObject类型的初始化值。此宏扩展为:

_PyObject_EXTRA_INIT
1, type,
PyVarObject_HEAD_INIT(type, size)

这是一个宏,扩展为新的PyVarObject类型的初始化值,包括ob_size字段。此宏扩展为:

_PyObject_EXTRA_INIT
1, type, size,
PyCFunction

这种类型的函数使用两个PyObject*参数并返回一个这样的值。如果返回值为NULL,则应设置异常。如果不是NULL,则返回值被解释为Python中公开的函数的返回值。该函数必须返回一个新的引用。

PyCFunctionWithKeywords

用于在C中实现Python可调用函数的函数的类型,它们接受关键字参数:它们需要三个PyObject*参数并返回一个这样的值。有关返回值的含义,请参见上面的PyCFunction

PyMethodDef

用于描述扩展类型的方法的结构。这个结构有四个字段:

领域C类型含义
ml_namechar *方法的名称
ml_methPyCFunction指向C实现的指针
ml_flagsint标志位指示应如何构造呼叫
ml_docchar *指向docstring的内容

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

ml_flags字段是可以包括以下标志的位字段。各个标志表示调用约定或绑定约定。在调用约定标志中,只能组合METH_VARARGSMETH_KEYWORDS任何调用约定标志可以与绑定标志组合。

METH_VARARGS

这是典型的调用约定,其中方法具有类型PyCFunction该函数需要两个PyObject*值。第一个是方法的self对象;对于模块函数,它是模块对象。第二个参数(通常称为args)是一个表示所有参数的元组对象。此参数通常使用PyArg_ParseTuple()PyArg_UnpackTuple()进行处理。

METH_KEYWORDS

具有这些标志的方法必须是PyCFunctionWithKeywords类型。该函数需要三个参数:selfargs和所有关键字参数的字典。该标志通常与METH_VARARGS组合,并且通常使用PyArg_ParseTupleAndKeywords()来处理参数。

METH_NOARGS

没有参数的方法不需要检查是否给出参数,如果它们与METH_NOARGS标志一起列出。它们需要是PyCFunction类型。第一个参数通常命名为self,并且将保存对模块或对象实例的引用。在所有情况下,第二个参数将为NULL

METH_O

具有单个对象参数的方法可以使用METH_O标志列出,而不是使用"O"参数调用PyArg_ParseTuple()它们具有PyCFunction类型,其中包含self参数和表示单个参数的PyObject*参数。

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

METH_CLASS

该方法将传递type对象作为第一个参数,而不是类型的实例。这用于创建类方法,类似于使用classmethod()内建函数时创建的方法。

METH_STATIC

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

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

METH_COEXIST

将加载该方法以代替现有定义。如果没有METH_COEXIST,则默认跳过重复的定义。由于在方法表之前加载了槽包装,例如,存在sq_contains槽将生成名为__contains__(),并排除加载相应的PyCFunction具有相同的名称。使用定义的标志,PyCFunction将被加载代替包装器对象,并且将与槽共存。这是有帮助的,因为对PyCFunctions的调用比包装器对象调用更优化。

PyMemberDef

描述对应于C结构成员的类型的属性的结构。其字段为:

领域C类型含义
namechar *成员的名称
typeint成员在C struct中的类型
offsetPy_ssize_t成员位于类型的对象struct上的字节偏移量
flagsint标志位,指示该字段是只读还是可写
docchar *指向docstring的内容

type可以是与各种C类型相对应的许多T_宏中的一个。当在Python中访问成员时,它将被转换为等效的Python类型。

宏名称C型
T_SHORT
着色int
T_LONG
T_FLOAT浮动
T_DOUBLE
T_STRINGchar *
T_OBJECTPyObject *
T_OBJECT_EXPyObject *
T_CHARchar
T_BYTEchar
T_UBYTE无符号字符
T_UINTunsigned int
T_USHORT无符号短
T_ULONGunsigned long
T_BOOLchar
T_LONGLONG长长
T_ULONGLONGunsigned long long
T_PYSSIZETPy_ssize_t

T_OBJECT and T_OBJECT_EX differ in that T_OBJECT returns None if the member is NULL and T_OBJECT_EX raises an AttributeError. Try to use T_OBJECT_EX over T_OBJECT because T_OBJECT_EX handles use of the del statement on that attribute more correctly than T_OBJECT.

flags对于写入和读取访问可以为0,对于只读访问可以为READONLYtype使用T_STRING意味着READONLY只能删除T_OBJECTT_OBJECT_EX成员。(它们设置为NULL)。