公共对象结构¶
在定义Python的对象类型时,使用了大量的结构。本节介绍这些结构及其使用方法。
基本对象类型和宏¶
所有的python对象最终在对象在内存中表示的开头共享少量的字段。它们由 PyObject
和 PyVarObject
类型,这些类型又由一些宏的扩展来定义,无论是直接还是间接地,在所有其他python对象的定义中也使用这些宏。
-
type PyObject¶
所有对象类型都是此类型的扩展。这是一个包含Python将对象指针视为对象所需信息的类型。在正常的“发布”构建中,它只包含对象的引用计数和指向相应类型对象的指针。实际上没有任何东西被声明为
PyObject
但每个指向python对象的指针都可以强制转换为 PyObject* . 必须使用宏来访问成员Py_REFCNT
和Py_TYPE
.
-
type PyVarObject¶
这是对
PyObject
增加了ob_size
字段。这仅用于具有以下概念的对象 长度 . 这种类型不经常出现在python/c API中。必须使用宏来访问成员Py_REFCNT
,Py_TYPE
和Py_SIZE
.
-
PyObject_VAR_HEAD¶
这是一个宏,用于声明表示不同实例长度的对象的新类型。pyobject_var_head宏扩展到:
PyVarObject ob_base;
参见文档
PyVarObject
上面。
-
PyTypeObject *Py_TYPE(const PyObject *o)¶
获取Python对象的类型 o .
返回一个 borrowed reference 。
这个
Py_SET_TYPE()
函数必须用于设置对象类型。
-
int Py_IS_TYPE(PyObject *o, PyTypeObject *type)¶
如果对象为 o 类型是 type . 否则返回零。相当于:
Py_TYPE(o) == type
.3.9 新版功能.
-
void Py_SET_TYPE(PyObject *o, PyTypeObject *type)¶
设置对象 o 类型到 type .
3.9 新版功能.
-
Py_ssize_t Py_REFCNT(const PyObject *o)¶
获取Python对象的引用计数 o .
在 3.10 版更改:
Py_REFCNT()
更改为内联静态函数。使用Py_SET_REFCNT()
设置对象引用计数。
-
Py_ssize_t Py_SIZE(const PyVarObject *o)¶
获取Python对象的大小 o .
这个
Py_SET_SIZE()
函数必须用于设置对象大小。
-
void Py_SET_SIZE(PyVarObject *o, Py_ssize_t size)¶
设置对象 o 尺寸至 size .
3.9 新版功能.
-
PyVarObject_HEAD_INIT(type, size)¶
这是一个宏,它扩展为新的
PyVarObject
类型,包括ob_size
字段。此宏扩展为:_PyObject_EXTRA_INIT 1, type, size,
实现功能和方法¶
-
type PyCFunction¶
用于在C中实现大多数python可调用文件的函数的类型。此类型的函数有两个 PyObject* 并返回一个这样的值。如果返回值为
NULL
,应设置例外。如果没有NULL
,返回值被解释为在python中公开的函数的返回值。函数必须返回新的引用。函数签名为:
PyObject *PyCFunction(PyObject *self, PyObject *args);
-
type PyCFunctionWithKeywords¶
用于在带有签名的C中实现python可调用文件的函数的类型
METH_VARARGS | METH_KEYWORDS
. 函数签名是:PyObject *PyCFunctionWithKeywords(PyObject *self, PyObject *args, PyObject *kwargs);
-
type _PyCFunctionFast¶
用于在带有签名的C中实现python可调用文件的函数的类型
METH_FASTCALL
. 函数签名是:PyObject *_PyCFunctionFast(PyObject *self, PyObject *const *args, Py_ssize_t nargs);
-
type _PyCFunctionFastWithKeywords¶
用于在带有签名的C中实现python可调用文件的函数的类型
METH_FASTCALL | METH_KEYWORDS
. 函数签名是:PyObject *_PyCFunctionFastWithKeywords(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames);
-
type PyCMethod¶
用于在带有签名的C中实现python可调用文件的函数的类型
METH_METHOD | METH_FASTCALL | METH_KEYWORDS
. 函数签名是:PyObject *PyCMethod(PyObject *self, PyTypeObject *defining_class, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
3.9 新版功能.
-
type PyMethodDef¶
用于描述扩展类型的方法的结构。此结构有四个字段:
场
C型
意义
ml_name
常量字符 *
方法的名称
ml_meth
PyCFunction
指向C实现的指针
ml_flags
int
指示如何构造调用的标志位
ml_doc
常量字符 *
指向docstring的内容
这个 ml_meth
是C函数指针。函数可以是不同的类型,但它们总是返回 PyObject* . 如果函数不是 PyCFunction
编译器将需要在方法表中进行强制转换。尽管 PyCFunction
将第一个参数定义为 PyObject* ,方法实现通常使用 self 对象。
这个 ml_flags
字段是可以包含以下标志的位字段。各个标志指示调用约定或绑定约定。
有以下调用约定:
- METH_VARARGS¶
这是典型的调用约定,其中方法具有
PyCFunction
. 函数需要两个 PyObject* 价值观。第一个是 self 方法的对象;对于模块函数,它是模块对象。第二个参数(通常称为 args )是表示所有参数的元组对象。此参数通常使用PyArg_ParseTuple()
或PyArg_UnpackTuple()
.
- METH_VARARGS | METH_KEYWORDS
具有这些标志的方法的类型必须为
PyCFunctionWithKeywords
. 函数需要三个参数: self , args , 关键字参数 在哪里? 关键字参数 是所有关键字参数的字典,或者可能是NULL
如果没有关键字参数。通常使用PyArg_ParseTupleAndKeywords()
.
- METH_FASTCALL¶
仅支持位置参数的快速调用约定。方法具有类型
_PyCFunctionFast
. 第一个参数是 self ,第二个参数是 PyObject* 指示参数的值和第三个参数是参数的数目(数组的长度)。3.7 新版功能.
在 3.10 版更改:
METH_FASTCALL
现在是稳定的ABI的一部分。
- METH_FASTCALL | METH_KEYWORDS
延期
METH_FASTCALL
还支持关键字参数,方法类型为_PyCFunctionFastWithKeywords
. 关键字参数的传递方式与 vectorcall protocol :还有第四个 PyObject* 参数,它是一个元组,表示关键字参数的名称(保证为字符串),或者NULL
如果没有关键字。关键字参数的值存储在 args 数组,在位置参数之后。这不是 limited API .
3.7 新版功能.
- METH_METHOD | METH_FASTCALL | METH_KEYWORDS
延期
METH_FASTCALL | METH_KEYWORDS
支持 定义类 ,即,包含有问题的方法的类。定义类可能是Py_TYPE(self)
.方法必须是
PyCMethod
,与METH_FASTCALL | METH_KEYWORDS
具有defining_class
参数添加在后面self
.3.9 新版功能.
- METH_NOARGS¶
不带参数的方法不需要检查是否给定参数(如果这些参数与
METH_NOARGS
旗帜。它们必须是类型PyCFunction
. 第一个参数通常命名为 self 并保存对模块或对象实例的引用。在所有情况下,第二个参数将是NULL
.
- METH_O¶
具有单个对象参数的方法可以与
METH_O
标记,而不是调用PyArg_ParseTuple()
用一个"O"
争论。他们有这种类型PyCFunction
与 self 参数,以及 PyObject* 表示单个参数的参数。
这两个常量不用于指示调用约定,而是用于类方法时的绑定。这些不能用于为模块定义的函数。对于任何给定的方法,最多可以设置其中一个标志。
- METH_CLASS¶
方法将作为第一个参数而不是类型的实例传递类型对象。用于创建 类方法 ,类似于使用
classmethod()
内置功能。
- METH_STATIC¶
方法将被传递
NULL
作为第一个参数而不是类型的实例。用于创建 静态方法 ,类似于使用staticmethod()
内置功能。
另一个常量控制是否在加载方法时替换具有相同方法名称的另一个定义。
- METH_COEXIST¶
将加载该方法以取代现有的定义。没有 METH_COEXIST ,默认值是跳过重复的定义。由于槽封装器在方法表之前加载,因此 sq_contains 例如,slot将生成一个名为
__contains__()
并排除加载具有相同名称的相应PycFunction。定义了标志后,PycFunction将代替封装器对象加载,并与槽共存。这很有用,因为对pycfunctions的调用比封装对象调用优化得多。
访问扩展类型的属性¶
-
type PyMemberDef¶
结构,它描述与C结构成员对应的类型的属性。它的领域是:
场
C型
意义
name
常量字符 *
成员的姓名
type
int
C结构中成员的类型
offset
Py_ssize_t
成员位于类型的对象结构上的偏移量(以字节为单位)
flags
int
指示字段是只读还是可写的标志位
doc
常量字符 *
指向docstring的内容
type
可以是很多人中的一个T_
与各种C类型相对应的宏。当在python中访问该成员时,它将转换为等效的python类型。宏名称
C型
T_SHORT
短的
T_INT
int
T_LONG
长的
T_FLOAT
浮动
T_DOUBLE
双重的
T_STRING
常量字符 *
T_OBJECT
PyObject *
T_OBJECT_EX
PyObject *
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
提出一个AttributeError
. 尝试使用T_OBJECT_EX
结束T_OBJECT
因为T_OBJECT_EX
处理的使用del
对该属性的声明比T_OBJECT
.flags
可以是0
用于读写访问或READONLY
用于只读访问。使用T_STRING
对于type
暗示READONLY
.T_STRING
数据被解释为UTF-8。只有T_OBJECT
和T_OBJECT_EX
可以删除成员。(设置为NULL
)堆分配类型(使用
PyType_FromSpec()
或类似的),PyMemberDef
可包含特殊成员的定义__dictoffset__
,__weaklistoffset__
和__vectorcalloffset__
,对应于tp_dictoffset
,tp_weaklistoffset
和tp_vectorcall_offset
在类型对象中。必须用T_PYSSIZET
和READONLY
例如:static PyMemberDef spam_type_members[] = { {"__dictoffset__", T_PYSSIZET, offsetof(Spam_object, dict), READONLY}, {NULL} /* Sentinel */ };
-
type PyGetSetDef¶
用于定义类型的访问等属性的结构。另请参见
PyTypeObject.tp_getset
狭槽。场
C型
意义
名称
常量字符 *
属性名
得到
吸气剂
C函数获取属性
设置
设定器
用于设置或删除属性的可选C函数,如果省略,则该属性为只读
doc
常量字符 *
可选文档字符串
关闭
无效 *
可选的函数指针,为getter和setter提供附加数据
这个
get
函数取一 PyObject* 参数(实例)和函数指针(关联的closure
):typedef PyObject *(*getter)(PyObject *, void *);
它应该在成功时返回一个新的引用,或者
NULL
失败时出现设置异常。set
功能需要两个 PyObject* 参数(实例和要设置的值)和函数指针(关联的closure
):typedef int (*setter)(PyObject *, PyObject *, void *);
如果应删除属性,则第二个参数是
NULL
. 应该返回0
关于成功还是-1
失败时出现设置异常。