通用对象结构 — Python 文档

来自菜鸟教程
Python/docs/2.7/c-api/structures
跳转至:导航、​搜索

通用对象结构

在 Python 的对象类型定义中使用了大量结构。 本节介绍这些结构以及如何使用它们。

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

type PyObject
所有对象类型都是这种类型的扩展。 这是一种包含 Python 需要将指向对象的指针视为对象的信息的类型。 在正常的“发布”构建中,它仅包含对象的引用计数和指向相应类型对象的指针。 它对应于由 PyObject_HEAD 宏的扩展定义的字段。
type PyVarObject
这是 PyObject 的扩展,添加了 ob_size 字段。 这仅用于具有 长度 某种概念的对象。 这种类型并不经常出现在 Python/C API 中。 它对应于由 PyObject_VAR_HEAD 宏的扩展定义的字段。

这些宏用于 PyObjectPyVarObject 的定义:

PyObject_HEAD

这是一个宏,它扩展到 PyObject 类型的字段的声明; 它在声明表示没有变化长度的对象的新类型时使用。 它扩展到的具体字段取决于 Py_TRACE_REFS 的定义。 默认情况下,该宏未定义,PyObject_HEAD 扩展为:

Py_ssize_t ob_refcnt;
PyTypeObject *ob_type;

当定义 Py_TRACE_REFS 时,它扩展为:

PyObject *_ob_next, *_ob_prev;
Py_ssize_t ob_refcnt;
PyTypeObject *ob_type;
PyObject_VAR_HEAD

这是一个宏,它扩展到 PyVarObject 类型的字段的声明; 它用于声明表示长度因实例而异的对象的新类型。 此宏始终扩展为:

PyObject_HEAD
Py_ssize_t ob_size;

注意 PyObject_HEAD 是扩展的一部分,其自身的扩展取决于 Py_TRACE_REFS 的定义。

Py_TYPE(o)

该宏用于访问 Python 对象的 ob_type 成员。 它扩展为:

(((PyObject*)(o))->ob_type)

2.6 版中的新功能。

Py_REFCNT(o)

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

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

2.6 版中的新功能。

Py_SIZE(o)

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

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

2.6 版中的新功能。

PyObject_HEAD_INIT(type)

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

_PyObject_EXTRA_INIT
1, type,
PyVarObject_HEAD_INIT(type, size)

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

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

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

场地

C型

意义

ml_name

字符 *

方法名称

ml_meth

函数

指向 C 实现的指针

ml_flags

整数

指示应如何构造调用的标志位

ml_doc

字符 *

指向文档字符串的内容

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_OLDARGS
此调用约定已弃用。 该方法必须是 PyCFunction 类型。 如果没有给出参数,则第二个参数是 NULL,如果只给出一个参数,则为单个对象,如果给出多个参数,则为对象元组。 使用此约定的函数无法区分具有多个参数的调用和使用元组作为唯一参数的调用。

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

METH_CLASS

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

2.3 版中的新功能。

METH_STATIC

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

2.3 版中的新功能。

另一个常量控制是否加载一个方法来代替具有相同方法名称的另一个定义。

METH_COEXIST

该方法将代替现有定义加载。 如果没有 METH_COEXIST,默认是跳过重复定义。 由于槽包装器在方法表之前加载,例如,sq_contains 槽的存在将生成名为 __contains__() 的包装方法,并阻止加载具有相同名称的相应 PyCFunction . 定义标志后,PyCFunction 将代替包装器对象加载,并将与插槽共存。 这很有用,因为对 PyCFunction 的调用比包装器对象调用更优化。

2.4 版中的新功能。

type PyMemberDef

描述与 C 结构成员对应的类型的属性的结构。 它的字段是:

场地

C型

意义

name

字符 *

会员姓名

type

整数

C 结构体中成员的类型

offset

py_ssize_t

成员在类型的对象结构上的偏移量(以字节为单位)

flags

整数

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

doc

字符 *

指向文档字符串的内容

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

宏名称

C型

T_SHORT

短的

着色

整数

T_LONG

T_FLOAT

漂浮

T_DOUBLE

双倍的

T_STRING

字符 *

T_OBJECT

对象 *

T_OBJECT_EX

对象 *

T_CHAR

字符

T_BYTE

字符

T_UBYTE

无符号字符

T_UINT

无符号整数

T_USHORT

无符号短

T_ULONG

无符号长

T_BOOL

字符

T_LONGLONG

长长的

T_ULONGLONG

无符号长长

T_PYSSIZET

py_ssize_t

T_OBJECTT_OBJECT_EX 的不同在于 T_OBJECT 返回 None 如果成员是 NULL 并且 T_OBJECT_EX 引发 [ X122X]。 尝试在 T_OBJECT 上使用 T_OBJECT_EX,因为 T_OBJECT_EXT_OBJECT 更正确地处理对该属性的 del 语句的使用。

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

type PyGetSetDef

为类型定义类似属性的访问的结构。 另请参阅 PyTypeObject.tp_getset 插槽的描述。

场地

C型

意义

名称

字符 *

属性名

得到

吸气剂

C函数获取属性

二传手

可选的 C 函数来设置或删除属性,如果省略该属性是只读的

文档

字符 *

可选的文档字符串

关闭

空白 *

可选的函数指针,为 getter 和 setter 提供额外的数据

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

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

它应该在成功时返回一个新的引用,或者在失败时返回 NULL 并设置异常。

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

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

如果属性应该被删除,第二个参数是 NULL。 成功时应返回 0 或失败时返回 -1 并设置异常。

PyObject *Py_FindMethod(PyMethodDef table[], PyObject *ob, char *name)
返回在 C 中实现的扩展类型的绑定方法对象。 这在不使用 PyObject_GenericGetAttr() 函数的 tp_getattrotp_getattr 处理程序的实现中很有用。