分析参数并生成值

这些函数在创建自己的扩展函数和方法时很有用。其他信息和示例可在 扩展和嵌入python解释器 .

前三个功能描述, PyArg_ParseTuple()PyArg_ParseTupleAndKeywords()PyArg_Parse() 所有使用 格式串 用来告诉函数期望的参数。格式字符串对每个函数使用相同的语法。

正在分析参数

格式字符串由零个或多个“格式单位”组成。格式单位描述一个python对象;它通常是单个字符或带括号的格式单位序列。除了少数例外,不是带括号序列的格式单元通常对应于这些函数的单个地址参数。在下面的描述中,带引号的表单是格式单位;圆括号中的条目是与格式单位匹配的python对象类型;以及中的条目 [广场] 括号是应传递其地址的C变量的类型。

字符串和缓冲区

这些格式允许作为连续内存块访问对象。您不必为返回的unicode或bytes区域提供原始存储。

通常,当一个格式设置指向缓冲区的指针时,缓冲区由相应的python对象管理,缓冲区共享该对象的生存期。你不必自己释放任何记忆。唯一的例外是 eses#etet# .

但是,当 Py_buffer 结构被填满,底层缓冲区被锁定,以便调用方随后可以使用缓冲区,即使在 Py_BEGIN_ALLOW_THREADS 阻止而不存在可变数据被调整大小或破坏的风险。因此, 你得调用 PyBuffer_Release() 完成数据处理后(或在任何早期中止情况下)。

除非另有说明,否则缓冲区不会被nul终止。

某些格式需要只读 bytes-like object ,并设置指针而不是缓冲区结构。他们通过检查物体的 PyBufferProcs.bf_releasebuffer 字段是 NULL 不允许可变对象,例如 bytearray .

注解

为了所有 # 格式的变体 (s#y# 等),宏 PY_SSIZE_T_CLEAN 必须在包括 Python.h . 在Python3.9及更高版本上,length参数的类型是 Py_ssize_t 如果 PY_SSIZE_T_CLEAN 宏已定义,否则为int。

s (str ) [const char *]

将Unicode对象转换为指向字符串的C指针。指向现有字符串的指针存储在您传递地址的字符指针变量中。C字符串以nul结尾。python字符串不能包含嵌入的空代码点;如果包含,则 ValueError 引发异常。Unicode对象转换为C字符串时使用 'utf-8' 编码。如果转换失败,则 UnicodeError 提高了。

注解

此格式不接受 bytes-like objects . 如果要接受文件系统路径并将其转换为C字符串,最好使用 O& 格式与 PyUnicode_FSConverter() 作为 转换器 .

在 3.5 版更改: 以前, TypeError 在python字符串中遇到嵌入的空代码点时引发。

s* (strbytes-like object ) [Py_buffer]

此格式接受Unicode对象以及类似对象的字节。它充满了 Py_buffer 调用方提供的结构。在这种情况下,生成的C字符串可能包含嵌入的nul字节。Unicode对象转换为C字符串时使用 'utf-8' 编码。

s# (str, read-only bytes-like object) [const char *, Py_ssize_t]

类似于 s* ,但它不接受可变对象。结果存储在两个C变量中,第一个是指向C字符串的指针,第二个是它的长度。字符串可能包含嵌入的空字节。Unicode对象转换为C字符串时使用 'utf-8' 编码。

z (strNone ) [const char *]

喜欢 s 但python对象也可能是 None ,在这种情况下,C指针设置为 NULL .

z* (strbytes-like objectNone ) [Py_buffer]

喜欢 s* 但python对象也可能是 None ,在这种情况下, buf 会员 Py_buffer 结构设置为 NULL .

z# (str, read-only bytes-like object or None) [const char *, Py_ssize_t]

喜欢 s# 但python对象也可能是 None ,在这种情况下,C指针设置为 NULL .

y (只读) bytes-like object ) [const char *]

此格式将类似对象的字节转换为指向字符串的C指针;它不接受Unicode对象。字节缓冲区不能包含嵌入的空字节;如果包含,则 ValueError 引发异常。

在 3.5 版更改: 以前, TypeError 在字节缓冲区中遇到嵌入的空字节时引发。

y* (bytes-like object ) [Py_buffer]

这种变体 s* 不接受Unicode对象,只接受类似对象的字节。 这是接受二进制数据的推荐方法。

y# (只读) bytes-like object ) [const char *, Py_ssize_t]

这种变体 s# 不接受Unicode对象,只接受类似对象的字节。

S (bytes ) [PyBytesObject *]

要求python对象是 bytes 对象,而不尝试任何转换。加薪 TypeError 如果对象不是字节对象。C变量也可以声明为 PyObject* .

Y (bytearray ) [PyByteArrayObject *]

要求python对象是 bytearray 对象,而不尝试任何转换。加薪 TypeError 如果对象不是 bytearray 对象。C变量也可以声明为 PyObject* .

u (str ) [const Py_UNICODE *]

将python unicode对象转换为指向以nul结尾的unicode字符缓冲区的C指针。你必须把地址传给 Py_UNICODE 指针变量,将用指向现有Unicode缓冲区的指针填充。请注意A的宽度 Py_UNICODE 字符取决于编译选项(16位或32位)。python字符串不能包含嵌入的空代码点;如果包含,则 ValueError 引发异常。

在 3.5 版更改: 以前, TypeError 在python字符串中遇到嵌入的空代码点时引发。

Deprecated since version 3.3, will be removed in version 4.0: 旧风格的一部分 Py_UNICODE API;请迁移到使用 PyUnicode_AsWideCharString() .

u# (str) [const Py_UNICODE *, Py_ssize_t]

这种变体 u 存储到两个C变量中,第一个是指向Unicode数据缓冲区的指针,第二个是其长度。此变量允许空代码点。

Deprecated since version 3.3, will be removed in version 4.0: 旧风格的一部分 Py_UNICODE API;请迁移到使用 PyUnicode_AsWideCharString() .

Z (strNone ) [const Py_UNICODE *]

喜欢 u 但python对象也可能是 None ,在这种情况下, Py_UNICODE 指针设置为 NULL .

Deprecated since version 3.3, will be removed in version 4.0: 旧风格的一部分 Py_UNICODE API;请迁移到使用 PyUnicode_AsWideCharString() .

Z# (str or None) [const Py_UNICODE *, Py_ssize_t]

喜欢 u# 但python对象也可能是 None ,在这种情况下, Py_UNICODE 指针设置为 NULL .

Deprecated since version 3.3, will be removed in version 4.0: 旧风格的一部分 Py_UNICODE API;请迁移到使用 PyUnicode_AsWideCharString() .

U (str ) [PyObject *]

要求python对象是Unicode对象,而不尝试任何转换。加薪 TypeError 如果对象不是Unicode对象。C变量也可以声明为 PyObject* .

w* (读写) bytes-like object ) [Py_buffer]

此格式接受实现读写缓冲区接口的任何对象。它充满了 Py_buffer 调用方提供的结构。缓冲区可能包含嵌入的空字节。调用的人必须调用 PyBuffer_Release() 当缓冲区完成后。

es (str ) [const char *encoding, char **buffer]

这种变体 s 用于将Unicode编码到字符缓冲区中。它只适用于没有嵌入nul字节的编码数据。

此格式需要两个参数。第一个仅用作输入,必须是 const char* 以nul结尾的字符串的形式指向编码的名称,或者 NULL ,在这种情况下 'utf-8' 使用编码。如果Python不知道命名编码,则会引发异常。第二个参数必须是 char** ;它引用的指针的值将设置为包含参数文本内容的缓冲区。文本将按第一个参数指定的编码进行编码。

PyArg_ParseTuple() 将分配所需大小的缓冲区,将编码数据复制到此缓冲区并调整 *buffer 引用新分配的存储。调用方负责调用 PyMem_Free() 在使用后释放分配的缓冲区。

et (strbytesbytearray ) [const char *encoding, char **buffer]

等同于 es 除了字节字符串对象是在不重新编码的情况下传递的。相反,实现假定字节字符串对象使用作为参数传入的编码。

es# (str) [const char *encoding, char **buffer, Py_ssize_t *buffer_length]

这种变体 s# 用于将Unicode编码到字符缓冲区中。不同于 es 格式,此变量允许输入包含nul字符的数据。

它需要三个参数。第一个仅用作输入,必须是 const char* 以nul结尾的字符串的形式指向编码的名称,或者 NULL ,在这种情况下 'utf-8' 使用编码。如果Python不知道命名编码,则会引发异常。第二个参数必须是 char** ;它引用的指针的值将设置为包含参数文本内容的缓冲区。文本将按第一个参数指定的编码进行编码。第三个参数必须是指向整数的指针;引用的整数将被设置为输出缓冲区中的字节数。

有两种操作模式:

如果 *buffer A点 NULL 指针,函数将分配所需大小的缓冲区,将编码的数据复制到此缓冲区并设置 *buffer 引用新分配的存储。呼叫方负责呼叫 PyMem_Free() 在使用后释放分配的缓冲区。

如果 *buffer 指向非“空”指针(已分配的缓冲区), PyArg_ParseTuple() 将使用此位置作为缓冲区并解释 *buffer_length 作为缓冲区大小。然后它将把编码的数据复制到缓冲区中,然后nul终止它。如果缓冲区不够大, ValueError 将被设置。

在这两种情况下, *buffer_length 设置为不带尾随nul字节的编码数据的长度。

et# (str, bytes or bytearray) [const char *encoding, char **buffer, Py_ssize_t *buffer_length]

等同于 es# 除了字节字符串对象是在不重新编码的情况下传递的。相反,实现假定字节字符串对象使用作为参数传入的编码。

数字

b (int ) [无符号字符]

将非负的python整数转换为无符号的微小int,存储在c中 unsigned char .

B (int ) [无符号字符]

将python整数转换为微小的int,而不进行溢出检查,存储在C中 unsigned char .

h (int ) [短整型]

将python整数转换为c short int .

H (int ) [无符号短整型]

将python整数转换为c unsigned short int ,不进行溢出检查。

i (int ) [int]

将python整数转换为普通C int .

I (int ) [无符号整型]

将python整数转换为c unsigned int ,不进行溢出检查。

l (int ) [长整型]

将python整数转换为c long int .

k (int ) [无符号长]

将python整数转换为c unsigned long 无溢出检查。

L (int ) [长长]

将python整数转换为c long long .

K (int ) [无符号长整型]

将python整数转换为c unsigned long long 无溢出检查。

n (int ) [Py_ssize_t]

将python整数转换为c Py_ssize_t .

c (bytesbytearray 长度1) [char]

转换python字节,表示为 bytesbytearray 对象长度为1,到a c char .

在 3.3 版更改: 允许 bytearray 物体。

C (str 长度1) [int]

转换python字符,表示为 str 对象长度为1,到a c int .

f (float ) [浮动]

将python浮点数转换为C float .

d (float ) [双重的]

将python浮点数转换为C double .

D (complex ) [Py_complex]

将python复数转换为C Py_complex 结构。

其他对象

O (对象) [PyObject *]

将python对象(不进行任何转换)存储在C对象指针中。因此,C程序接收传递的实际对象。对象的引用计数没有增加。存储的指针不是 NULL .

O! (对象) [typeobject, PyObject *]

将python对象存储在C对象指针中。这和 O ,但采用两个C参数:第一个是python类型对象的地址,第二个是c变量的地址(类型为 PyObject* )对象指针存储在其中。如果python对象没有所需的类型, TypeError 提高了。

O& (对象) [converter, anything]

通过将python对象转换为C变量 转换器 功能。这需要两个参数:第一个是函数,第二个是C变量(任意类型)的地址,转换为 void* . 这个 转换器 依次调用函数如下:

status = converter(object, address);

在哪里? 对象 是要转换的python对象,并且 地址void* 传递给 PyArg_Parse* 功能。归还的人 地位 应该是 1 为了成功的转换和 0 如果转换失败。当转换失败时, 转换器 函数应引发异常并保留 地址 未修改的

如果 转换器 收益率 Py_CLEANUP_SUPPORTED 如果参数解析最终失败,则可能会再次调用它,从而给转换器释放已分配的任何内存的机会。在第二次通话中, 对象 参数将为 NULL地址 将具有与原始调用中相同的值。

在 3.1 版更改: Py_CLEANUP_SUPPORTED 加入。

p (bool ) [int]

测试传入的值是否为真(布尔值 p 并将结果转换为等效的C真/假整数值。将int设置为 1 如果表达式是真的并且 0 如果是假的话。它接受任何有效的python值。见 真值检验 有关Python如何测试值的真实性的更多信息。

3.3 新版功能.

(items) (tuple ) [matching-items]

对象必须是一个python序列,其长度为 项目 . C参数必须对应于 项目 . 序列的格式单位可以嵌套。

可以传递“long”整数(其值超过平台的整数 LONG_MAX )然而,没有进行适当的范围检查---当接收字段太小而无法接收值时,最重要的位会自动截断(实际上,语义是从C中的向下转换继承的---您的里程可能会有所不同)。

其他几个字符在格式字符串中有意义。这些不能出现在嵌套的括号内。他们是:

|

指示python参数列表中的其余参数是可选的。与可选参数对应的C变量应初始化为其默认值---如果未指定可选参数, PyArg_ParseTuple() 不接触相应C变量的内容。

$

PyArg_ParseTupleAndKeywords() 仅:指示python参数列表中的其余参数仅为关键字。目前,所有只包含关键字的参数也必须是可选参数,因此 | 必须在之前指定 $ 格式字符串中。

3.3 新版功能.

:

格式单位列表在此结束;冒号后面的字符串用作错误消息中的函数名(异常的“关联值”)。 PyArg_ParseTuple() 上升)。

;

格式单位列表在此结束;分号后面的字符串用作错误消息 相反 默认错误消息。 :; 相互排斥。

注意,提供给调用者的任何python对象引用都是 借来 引用;不要减少它们的引用计数!

传递给这些函数的其他参数必须是变量的地址,变量的类型由格式字符串决定;这些参数用于存储输入元组中的值。如上面的格式单位列表所述,有一些情况下,这些参数用作输入值;它们应该与在这种情况下为相应的格式单位指定的内容相匹配。

为了转化成功, arg 对象必须与格式匹配,并且格式必须用尽。论成功 PyArg_Parse* 函数返回true,否则返回false并引发适当的异常。当 PyArg_Parse* 函数由于某个格式单位的转换失败而失败,与该格式单位对应的地址处的变量和以下格式单位保持不变。

API函数

int PyArg_ParseTuple(PyObject *args, const char *format, ...)

分析只将位置参数带到局部变量中的函数的参数。成功时返回true;失败时返回false并引发适当的异常。

int PyArg_VaParse(PyObject *args, const char *format, va_list vargs)

相同的 PyArg_ParseTuple() ,但它接受一个va_列表,而不是一个变量个数的参数。

int PyArg_ParseTupleAndKeywords(PyObject *args, PyObject *kw, const char *format, char *keywords[], ...)

分析将位置参数和关键字参数都纳入局部变量的函数参数。这个 关键词 参数是 NULL -关键字参数名数组已终止。空名称表示 positional-only parameters . 成功时返回true;失败时返回false并引发适当的异常。

在 3.6 版更改: 为添加了支持 positional-only parameters .

int PyArg_VaParseTupleAndKeywords(PyObject *args, PyObject *kw, const char *format, char *keywords[], va_list vargs)

相同的 PyArg_ParseTupleAndKeywords() ,但它接受一个va_列表,而不是一个变量个数的参数。

int PyArg_ValidateKeywordArguments(PyObject*)

确保关键字参数字典中的键是字符串。只有在以下情况下才需要 PyArg_ParseTupleAndKeywords() 不使用,因为后者已执行此检查。

3.2 新版功能.

int PyArg_Parse(PyObject *args, const char *format, ...)

用于解构“老式”函数的参数列表的函数---这些函数使用 METH_OLDARGS 参数解析方法,已在python 3中删除。建议不要在新代码中的参数解析中使用此方法,并且标准解释器中的大多数代码都已修改为不再使用此方法。然而,它仍然是分解其他元组的一种方便方法,并且可能继续用于此目的。

int PyArg_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, ...)

一种更简单的参数检索形式,它不使用格式字符串来指定参数的类型。使用此方法检索其参数的函数应声明为 METH_VARARGS 在函数表或方法表中。包含实际参数的元组应该作为 args ;它实际上必须是一个元组。元组的长度必须至少为 min 而且不会超过 maxminmax 可能是相等的。必须将其他参数传递给函数,每个参数都应该是指向 PyObject* 变量;这些值将使用以下内容中的值填充 args ;它们将包含 borrowed references 。与未给出的可选参数相对应的变量 args 将不会填写;这些应由调用方初始化。此函数在成功时返回TRUE,如果成功则返回FALSE args 不是元组或包含错误数量的元素;如果出现故障,将设置异常。

这是使用此函数的示例,取自 _weakref 弱引用的帮助程序模块:

static PyObject *
weakref_ref(PyObject *self, PyObject *args)
{
    PyObject *object;
    PyObject *callback = NULL;
    PyObject *result = NULL;

    if (PyArg_UnpackTuple(args, "ref", 1, 2, &object, &callback)) {
        result = PyWeakref_NewRef(object, callback);
    }
    return result;
}

呼唤 PyArg_UnpackTuple() 在本例中,完全等同于调用 PyArg_ParseTuple() ::

PyArg_ParseTuple(args, "O|O:ref", &object, &callback)

创建值

PyObject *Py_BuildValue(const char *format, ...)
Return value: New reference.

基于类似于 PyArg_Parse* 函数族和值序列。返回值或 NULL 如果出现错误;如果 NULL 返回。

Py_BuildValue() 并不总是构建元组。仅当其格式字符串包含两个或多个格式单位时,才会构建元组。如果格式字符串为空,则返回 None ;如果它只包含一个格式单元,则返回该格式单元描述的任何对象。要强制它返回大小为0或1的元组,请将格式字符串用括号括起来。

当内存缓冲区作为参数传递以向生成对象提供数据时,例如 ss# 格式,复制所需数据。调用方提供的缓冲区从不被创建的对象引用 Py_BuildValue() . 换句话说,如果代码调用 malloc() 并将分配的内存传递给 Py_BuildValue() ,您的代码负责调用 free() 为了那个记忆 Py_BuildValue() 返回。

在下面的描述中,带引号的表单是格式单位;圆括号中的条目是格式单位将返回的python对象类型;以及中的条目 [广场] 括号是要传递的C值的类型。

格式字符串中的字符空格、制表符、冒号和逗号将被忽略(但不在格式单位内,如 s# )这可以用来使长格式字符串更具可读性。

s (strNone ) [const char *]

将以空结尾的C字符串转换为python str 对象使用 'utf-8' 编码。如果C字符串指针是 NULLNone 使用。

s# (str or None) [const char *, Py_ssize_t]

将C字符串及其长度转换为python str 对象使用 'utf-8' 编码。如果C字符串指针是 NULL ,长度被忽略,并且 None 返回。

y (bytes ) [const char *]

这将C字符串转换为python bytes 对象。如果C字符串指针是 NULLNone 返回。

y# (bytes) [const char *, Py_ssize_t]

这会将C字符串及其长度转换为python对象。如果C字符串指针是 NULLNone 返回。

z (strNone ) [const char *]

等同于 s .

z# (str or None) [const char *, Py_ssize_t]

等同于 s# .

u (str ) [const wchar_t *]

转换以空结尾的 wchar_t 将unicode(utf-16或ucs-4)数据缓冲到python unicode对象。如果unicode缓冲区指针是 NULLNone 返回。

u# (str) [const wchar_t *, Py_ssize_t]

将unicode(utf-16或ucs-4)数据缓冲区及其长度转换为python unicode对象。如果unicode缓冲区指针是 NULL ,长度被忽略,并且 None 返回。

U (strNone ) [const char *]

等同于 s .

U# (str or None) [const char *, Py_ssize_t]

等同于 s# .

i (int ) [int]

转换普通C int 到python integer对象。

b (int ) [char]

转换普通C char 到python integer对象。

h (int ) [短整型]

转换普通C short int 到python integer对象。

l (int ) [长整型]

转换C long int 到python integer对象。

B (int ) [无符号字符]

转换C unsigned char 到python integer对象。

H (int ) [无符号短整型]

转换C unsigned short int 到python integer对象。

I (int ) [无符号整型]

转换C unsigned int 到python integer对象。

k (int ) [无符号长]

转换C unsigned long 到python integer对象。

L (int ) [长长]

转换C long long 到python integer对象。

K (int ) [无符号长整型]

转换C unsigned long long 到python integer对象。

n (int ) [Py_ssize_t]

转换C Py_ssize_t 到python整数。

c (bytes 长度1) [char]

转换C int 将字节表示为python bytes 长度为1的对象。

C (str 长度1) [int]

转换C int 向python表示字符 str 长度为1的对象。

d (float ) [双重的]

转换C double 到python浮点数。

f (float ) [浮动]

转换C float 到python浮点数。

D (complex ) [Py_complex *]

转换C Py_complex 结构为python复数。

O (对象) [PyObject *]

传递一个未触及的python对象(引用计数除外,它的引用计数递增1)。如果传入的对象是 NULL 指针,假定这是由于生成参数的调用发现错误并设置了异常而导致的。因此, Py_BuildValue() 将返回 NULL 但不会引发例外。如果还没有提出例外, SystemError 被设置。

S (对象) [PyObject *]

等同于 O .

N (对象) [PyObject *]

等同于 O ,但它不会增加对象上的引用计数。当通过调用参数列表中的对象构造函数创建对象时很有用。

O& (对象) [converter, anything]

转换 任何东西 通过 转换器 功能。使用调用函数 任何东西 (应该与 void* )作为参数,应该返回“new”python对象,或者 NULL 如果发生错误。

(items) (tuple ) [matching-items]

将C值序列转换为项目数相同的python元组。

[items] (list ) [matching-items]

将C值序列转换为项目数相同的python列表。

{{items}} (dict ) [matching-items]

将C值序列转换为python字典。每对连续的C值向字典中添加一个项,分别作为键和值。

如果格式字符串中存在错误,则 SystemError 设置异常并 NULL 返回。

PyObject *Py_VaBuildValue(const char *format, va_list vargs)
Return value: New reference.

相同的 Py_BuildValue() ,但它接受一个va_列表,而不是一个变量个数的参数。