Skip to main content

公共对象结构

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

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

PyObject

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

PyVarObject

这是添加 ob_size 字段的 PyObject 的扩展。这只适用于有一些 length 概念的对象。此类型通常不会出现在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

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

PyCFunctionWithKeywords

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

PyMethodDef

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

领域

C类型

含义

ml_name

char *

方法的名称

ml_meth

PyCFunction

指向C实现的指针

ml_flags

int

标志位指示应如何构造呼叫

ml_doc

char *

指向docstring的内容

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

ml_flags 字段是可以包括以下标志的位字段。各个标志表示调用约定或绑定约定。在调用约定标志中,只有 METH_VARARGSMETH_KEYWORDS 可以组合(但是注意 METH_KEYWORDS 单独等同于 METH_VARARGS | METH_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类型

含义

name

char *

成员的名称

type

int

成员在C struct中的类型

offset

py_ssize_t

成员位于类型的对象struct上的字节偏移量

flags

int

标志位,指示该字段是只读还是可写

doc

char *

指向docstring的内容

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

宏名称

C型

T_SHORT

着色

int

T_LONG

T_FLOAT

浮动

T_DOUBLE

T_STRING

char *

T_OBJECT

PyObject *

T_OBJECT_EX

PyObject *

T_CHAR

char

T_BYTE

char

T_UBYTE

无符号字符

T_UINT

unsigned int

T_USHORT

无符号短

T_ULONG

unsigned long

T_BOOL

char

T_LONGLONG

长长

T_ULONGLONG

unsigned long long

T_PYSSIZET

py_ssize_t

T_OBJECTT_OBJECT_EX 的不同之处在于,如果成员是 NULL 并且 T_OBJECT_EX 产生 AttributeError,则 T_OBJECT 返回 None。尝试使用 T_OBJECT_EX over T_OBJECT,因为 T_OBJECT_EX 处理对该属性的 del 语句的使用比 T_OBJECT 更正确。

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