Skip to main content

解析参数和构建值

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

这些函数的前三个描述,PyArg_ParseTuple()PyArg_ParseTupleAndKeywords()PyArg_Parse(),都使用 格式字符串 来告诉函数关于期望的参数。格式字符串对这些函数使用相同的语法。

解析参数

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

字符串和缓冲区

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

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

然而,当 Py_buffer 结构被填充时,底层缓冲器被锁定,使得调用者可以随后甚至在 Py_BEGIN_ALLOW_THREADS 块内使用缓冲器,而没有可变数据被调整大小或被破坏的风险。因此,在您完成数据处理(或任何早期中止情况)后,你必须打电话 PyBuffer_Release()

除非另有说明,缓冲区不是NULL终止的。

一些格式需要只读 bytes-like object,并设置指针而不是缓冲区结构。他们通过检查对象的 PyBufferProcs.bf_releasebuffer 字段是否是 NULL 来工作,这不允许可变对象(如 bytearray)。

注解

对于所有 # 格式(s#y# 等)变体,通过在包括 Python.h 之前定义宏 PY_SSIZE_T_CLEAN 来控制长度自变量(int或 Py_ssize_t)的类型。如果定义了宏,length是 Py_ssize_t 而不是 int。此行为将在未来的Python版本中更改为仅支持 Py_ssize_t 并删除 int 支持。最好总是定义 PY_SSIZE_T_CLEAN

sstr)[const char *]

将Unicode对象转换为指向字符串的C指针。指向现有字符串的指针存储在您传递的地址的字符指针变量中。 C字符串是NUL终止的。 Python字符串不能包含嵌入的空代码点;如果是,则引发 ValueError 异常。 Unicode对象使用 'utf-8' 编码转换为C字符串。如果此转换失败,则会引发 UnicodeError

注解

此格式不接受 字节状对象。如果要接受文件系统路径并将其转换为C字符串,则最好使用带有 PyUnicode_FSConverter()O& 格式作为 converter

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

s*strbytes-like object)[Py_buffer]

此格式接受Unicode对象以及字节状对象。它填充由调用者提供的 Py_buffer 结构。在这种情况下,所得到的C字符串可以包含嵌入的NUL字节。 Unicode对象使用 'utf-8' 编码转换为C字符串。

s#str,只读 bytes-like object)[const char *,int或 Py_ssize_t]

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

zstrNone)[const char *]

s,但是Python对象也可以是 None,在这种情况下,C指针设置为 NULL

z*strbytes-like objectNone)[Py_buffer]

s*,但是Python对象也可以是 None,在这种情况下 Py_buffer 结构的 buf 成员设置为 NULL

z#str,只读 bytes-like objectNone)[const char *,int]

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 *,int]

s# 上的此变体不接受Unicode对象,只接受字节状对象。

Sbytes)[PyBytesObject *]

需要Python对象是 bytes 对象,而不尝试任何转换。如果对象不是字节对象,则提升 TypeError。 C变量也可以声明为 PyObject*

Ybytearray)[PyByteArrayObject *]

需要Python对象是 bytearray 对象,而不尝试任何转换。如果对象不是 bytearray 对象,则提升 TypeError。 C变量也可以声明为 PyObject*

ustr)[Py_UNICODE *]

将Python Unicode对象转换为C指针,指向NUL终止的Unicode字符缓冲区。您必须传递 Py_UNICODE 指针变量的地址,该变量将使用指向现有Unicode缓冲区的指针填充。请注意,Py_UNICODE 字符的宽度取决于编译选项(它是16位或32位)。 Python字符串不能包含嵌入的空代码点;如果是,则引发 ValueError 异常。

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

u#str)[Py_UNICODE *,int]

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

ZstrNone)[Py_UNICODE *]

u,但是Python对象也可以是 None,在这种情况下,Py_UNICODE 指针设置为 NULL

Z#strNone)[Py_UNICODE *,int]

u#,但是Python对象也可以是 None,在这种情况下,Py_UNICODE 指针设置为 NULL

Ustr)[PyObject *]

需要Python对象是Unicode对象,而不尝试任何转换。如果对象不是Unicode对象,则提升 TypeError。 C变量也可以声明为 PyObject*

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

此格式接受实现读写缓冲器接口的任何对象。它填充由调用者提供的 Py_buffer 结构。缓冲器可以包含嵌入的空字节。调用者在缓冲区完成后必须调用 PyBuffer_Release()

esstr)[const char *encoding,char **buffer]

s 上的此变体用于将Unicode编码为字符缓冲区。它仅适用于没有嵌入的NUL字节的编码数据。

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

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

etstrbytesbytearray)[const char *encoding,char **buffer]

es 相同,除了字节字符串对象通过而不重新编码。相反,实现假定字节字符串对象使用以as参数传递的编码。

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

s# 上的此变体用于将Unicode编码为字符缓冲区。与 es 格式不同,此变体允许包含NUL个字符的输入数据。

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

有两种操作模式:

如果 *buffer 指向一个 NULL 指针,函数将分配所需大小的缓冲区,将编码数据复制到此缓冲区中,并设置 *buffer 以引用新分配的存储。调用者负责在使用后调用 PyMem_Free() 释放分配的缓冲区。

如果 *buffer 指向非 NULL 指针(已分配的缓冲区),则 PyArg_ParseTuple() 将使用此位置作为缓冲区,并将 *buffer_length 的初始值解释为缓冲区大小。然后它将编码的数据复制到缓冲区并且NUL终止它。如果缓冲区不够大,将设置 ValueError

在这两种情况下,*buffer_length 被设置为没有后NUL字节的编码数据的长度。

et#strbytesbytearray)[const char *encoding,char **buffer,int *buffer_length]

es# 相同,除了字节字符串对象通过而不重新编码。相反,实现假定字节字符串对象使用以as参数传递的编码。

数字

bint)[unsigned char]

将非负的Python整数转换为存储在C unsigned char 中的unsigned tiny int。

Bint)[unsigned char]

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

hint)[short int]

将Python整数转换为C short int

Hint)[无符号短整型]

将Python整数转换为C unsigned short int,而不进行溢出检查。

iint)[int]

将Python整数转换为纯C int

Iint)[unsigned int]

将Python整数转换为C unsigned int,而不进行溢出检查。

lint)[long int]

将Python整数转换为C long int

kint)[无符号长整型]

将Python整数转换为C unsigned long,而不进行溢出检查。

Lint)[长]

将Python整数转换为C long long

Kint)[unsigned long long]

将Python整数转换为C unsigned long long,而不进行溢出检查。

nint)[Py_ssize_t]

将Python整数转换为C Py_ssize_t

c (长度为1的 bytesbytearray)[char]

将一个Python字节(表示为长度为1的 bytesbytearray 对象)转换为C char

在 3.3 版更改: 允许 bytearray 对象。

C (长度为1的 str)[int]

将表示为长度为1的 str 对象的Python字符转换为C int

ffloat)[float]

将Python浮点数转换为C float

dfloat)[双]

将Python浮点数转换为C double

Dcomplex)[Py_complex]

将Python的复数转换为C Py_complex 结构。

其他对象

O (object)[PyObject *]

将Python对象(无任何转换)存储在C对象指针中。 C程序因此接收被传递的实际对象。对象的引用计数不增加。存储的指针不是 NULL

O! (object)[typeobject,PyObject *]

将Python对象存储在C对象指针中。这与 O 类似,但是有两个C参数:第一个是Python类型对象的地址,第二个是存储对象指针的C变量(类型 PyObject*)的地址。如果Python对象没有必需的类型,则引发 TypeError

O& (object)[converteranything]

通过 converter 函数将Python对象转换为C变量。这需要两个参数:第一个是函数,第二个是C变量(任意类型)的地址,转换为 void *converter 函数又称为如下:

status = converter(object, address);

其中 object 是要转换的Python对象,address 是传递给 PyArg_Parse*() 函数的 void* 参数。返回的 status 应为成功转换的 1,如果转换失败,则为 0。当转换失败时,converter 函数应引发异常,并保留 address 的内容不被修改。

如果 converter 返回 Py_CLEANUP_SUPPORTED,如果参数解析最终失败,它可能会第二次被调用,从而使转换器有机会释放它已经分配的任何内存。在第二次调用中,object 参数将为NULL; address 将具有与原始调用中相同的值。

在 3.1 版更改: 加入 Py_CLEANUP_SUPPORTED

pbool)[int]

测试传入的值为真(布尔 p redicate),并将结果转换为其等效的C真/假整数值。如果表达式为true,则将int设置为 1,如果为false,则将 0 设置为AAAG。这接受任何有效的Python值。有关Python如何测试真值的值的更多信息,请参见 真值检验

3.3 新版功能.

(items)tuple)[matching-items]

对象必须是Python序列,其长度是 items 中格式单元的数量。 C参数必须对应于 items 中的各个格式单元。可以嵌套序列的格式单元。

可以传递“长”整数(其值超过平台的 LONG_MAX 的整数),但是没有进行适当的范围检查—当接收字段太小而不能接收值时,最高有效位被静默截断(实际上,语义是继承自C的downcasts - 你的里程可能会变化)。

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

|

表示Python参数列表中的其余参数是可选的。对应于可选参数的C变量应被初始化为其默认值—当未指定可选参数时,PyArg_ParseTuple() 不会触及相应C变量的内容。

$

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

3.3 新版功能.

:

格式单元列表在这里结束;冒号之后的字符串用作错误消息中的函数名(PyArg_ParseTuple() 引发的异常的“关联值”)。

;

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

注意,提供给调用者的任何Python对象引用都是 borrowed 引用;不要减少他们的引用计数!

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

为了转换成功,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_list而不是可变数量的参数。

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

解析将位置和关键字参数都转换为局部变量的函数的参数。 keywords 参数是一个 NULL 终止的关键字参数名称数组。空名称表示 仅位置参数。成功返回true;在失败时,它返回false并引发相应的异常。

在 3.6 版更改: 添加了对 仅位置参数 的支持。

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

PyArg_ParseTupleAndKeywords() 相同,除了它接受va_list而不是可变数量的参数。

int PyArg_ValidateKeywordArguments(PyObject *)

确保关键字参数字典中的键是字符串。这只有在不使用 PyArg_ParseTupleAndKeywords() 时才需要,因为后者已经进行了此检查。

3.2 新版功能.

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

用于解构“老式”函数的参数列表的函数—这些函数使用在Python 3中删除的 METH_OLDARGS 参数解析方法。这不推荐用于新代码中的参数解析,大多数标准解释器中的代码已被修改为不再使用此目的。然而,它仍然是分解其他元组的方便方式,并且可以继续用于该目的。

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

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

这是使用此函数的示例,取自 _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(),那么一旦 Py_BuildValue() 返回,你的代码就负责调用该内存的 free()

在下面的描述中,引用的形式是格式单元; (圆括号)中的条目是格式化单元将返回的Python对象类型;并且[正方形]括号中的条目是要传递的C值的类型。

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

sstrNone)[char *]

使用 'utf-8' 编码将使用空值终止的C字符串转换为Python str 对象。如果C字符串指针是 NULL,则使用 None

s#strNone)[char *,int]

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

ybytes)[char *]

这将一个C字符串转换为一个Python bytes 对象。如果C字符串指针是 NULL,则返回 None

y#bytes)[char *,int]

这将一个C字符串及其长度转换为一个Python对象。如果C字符串指针是 NULL,则返回 None

zstrNone)[char *]

s 相同。

z#strNone)[char *,int]

s# 相同。

ustr)[Py_UNICODE *]

将Unicode(UCS-2或UCS-4)数据的以null结尾的缓冲区转换为Python Unicode对象。如果Unicode缓冲区指针是 NULL,则返回 None

u#str)[Py_UNICODE *,int]

将Unicode(UCS-2或UCS-4)数据缓冲区及其长度转换为Python Unicode对象。如果Unicode缓冲区指针是 NULL,则忽略长度并返回 None

UstrNone)[char *]

s 相同。

U#strNone)[char *,int]

s# 相同。

iint)[int]

将纯C int 转换为Python整数对象。

bint)[char]

将纯C char 转换为Python整数对象。

hint)[short int]

将纯C short int 转换为Python整数对象。

lint)[long int]

将C long int 转换为Python整数对象。

Bint)[unsigned char]

将C unsigned char 转换为Python整数对象。

Hint)[无符号短整型]

将C unsigned short int 转换为Python整数对象。

Iint)[unsigned int]

将C unsigned int 转换为Python整数对象。

kint)[无符号长整型]

将C unsigned long 转换为Python整数对象。

Lint)[长]

将C long long 转换为Python整数对象。

Kint)[unsigned long long]

将C unsigned long long 转换为Python整数对象。

nint)[Py_ssize_t]

将C Py_ssize_t 转换为Python整数。

c (长度为1的 bytes)[char]

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

C (长度为1的 str)[int]

将表示一个字符的C int 转换为长度为1的Python str 对象。

dfloat)[双]

将C double 转换为Python浮点数。

ffloat)[float]

将C float 转换为Python浮点数。

Dcomplex)[Py_complex *]

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

O (object)[PyObject *]

传递一个Python对象(不包括它的引用计数,它增加一个)。如果传入的对象是 NULL 指针,则假定这是由于产生参数的调用发现错误并设置异常引起的。因此,Py_BuildValue() 将返回 NULL,但不会引发异常。如果还没有引发异常,则设置 SystemError

S (object)[PyObject *]

O 相同。

N (object)[PyObject *]

O 相同,除了它不增加对象上的引用计数。当对象通过调用参数列表中的对象构造函数创建时有用。

O& (object)[converteranything]

通过 converter 函数将 anything 转换为Python对象。该函数使用 anything (应与 void * 兼容)作为其参数调用,并应返回一个“新”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)

Py_BuildValue() 相同,除了它接受va_list而不是可变数量的参数。