通用对象结构 — Python 文档
通用对象结构
在 Python 的对象类型定义中使用了大量结构。 本节介绍这些结构以及如何使用它们。
所有 Python 对象最终在对象在内存中的表示开始时共享少量字段。 这些由 PyObject 和 PyVarObject 类型表示,这些类型又由一些宏的扩展来定义,这些宏在所有其他 Python 的定义中也直接或间接使用对象。
- type PyObject
- 所有对象类型都是这种类型的扩展。 这是一种包含 Python 需要将指向对象的指针视为对象的信息的类型。 在正常的“发布”构建中,它仅包含对象的引用计数和指向相应类型对象的指针。 它对应于由
PyObject_HEAD
宏的扩展定义的字段。
- type PyVarObject
- 这是 PyObject 的扩展,添加了
ob_size
字段。 这仅用于具有 长度 某种概念的对象。 这种类型并不经常出现在 Python/C API 中。 它对应于由PyObject_VAR_HEAD
宏的扩展定义的字段。
这些宏用于 PyObject 和 PyVarObject 的定义:
- 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_VARARGS 和 METH_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 标志列出具有单个对象参数的方法,而不是使用
"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_OBJECT
和T_OBJECT_EX
的不同在于T_OBJECT
返回None
如果成员是 NULL 并且T_OBJECT_EX
引发 [ X122X]。 尝试在T_OBJECT
上使用T_OBJECT_EX
,因为T_OBJECT_EX
比T_OBJECT
更正确地处理对该属性的 del 语句的使用。flags
可以是0
用于读写访问或READONLY
用于只读访问。 将T_STRING
用于 type 意味着READONLY
。 只能删除T_OBJECT
和T_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_getattro 或 tp_getattr 处理程序的实现中很有用。