解析参数和构建值 — Python 文档

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

解析参数和构建值

这些函数在创建您自己的扩展函数和方法时很有用。 更多信息和示例可在 扩展和嵌入 Python 解释器 中找到。

描述的这些函数中的前三个,PyArg_ParseTuple()PyArg_ParseTupleAndKeywords()PyArg_Parse(),都使用 格式字符串]用于告诉函数有关预期参数的信息。 格式字符串对这些函数中的每一个都使用相同的语法。

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

这些格式允许将对象作为连续的内存块进行访问。 您不必为返回的 unicode 或字节区域提供原始存储。 此外,您不必自己释放任何内存,eses#etet# 格式除外。

s(字符串或 Unicode)[const char *]

将 Python 字符串或 Unicode 对象转换为指向字符串的 C 指针。 您不得为字符串本身提供存储空间; 指向现有字符串的指针存储在您传递其地址的字符指针变量中。 C 字符串以 NUL 结尾。 Python 字符串不得包含嵌入的 NUL 字节; 如果是,则会引发 TypeError 异常。 Unicode 对象使用默认编码转换为 C 字符串。 如果此转换失败,则会引发 UnicodeError

s#(字符串、Unicode 或任何读取缓冲区兼容对象)[const char *、int(或 Py_ssize_t,见下文)]

s 上的这个变体存储到两个 C 变量中,第一个是指向字符串的指针,第二个是它的长度。 在这种情况下,Python 字符串可能包含嵌入的空字节。 如果这样的转换是可能的,Unicode 对象会传回一个指向对象的默认编码字符串版本的指针。 所有其他读取缓冲区兼容的对象都会传回对原始内部数据表示的引用。

从 Python 2.5 开始,可以通过在包含 Python.h 之前定义宏 PY_SSIZE_T_CLEAN 来控制长度参数的类型。 如果定义了宏,则长度为 Py_ssize_t 而不是 int。

s*(字符串、Unicode 或任何缓冲区兼容对象)[Py_buffer]

s#类似,这段代码填充了调用者提供的一个Py_buffer结构。 缓冲区被锁定,因此即使在 Py_BEGIN_ALLOW_THREADS 块内,调用者也可以随后使用缓冲区; 调用者负责在处理完数据后使用结构调用 PyBuffer_Release

2.6 版中的新功能。

z(字符串,Unicode 或 None)[const char *]

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

z#(字符串、Unicode、None 或任何读取缓冲区兼容对象)[const char *, int]

这对于 s# 就像 z 对于 s

z*(字符串,Unicode,None 或任何缓冲区兼容对象)[Py_buffer]

这对于 s* 就像 z 对于 s

2.6 版中的新功能。

u (Unicode) [Py_UNICODE *]

将 Python Unicode 对象转换为指向以 NUL 结尾的 16 位 Unicode (UTF-16) 数据缓冲区的 C 指针。 与s一样,不需要为Unicode数据缓冲区提供存储空间; 指向现有 Unicode 数据的指针存储在您传递的地址的 Py_UNICODE 指针变量中。

u# (Unicode) [Py_UNICODE *, int]

u 上的这个变体存储到两个 C 变量中,第一个是指向 Unicode 数据缓冲区的指针,第二个是它的长度。 非 Unicode 对象通过将它们的读取缓冲区指针解释为指向 Py_UNICODE 数组的指针来处理。

es(字符串、Unicode 或字符缓冲区兼容对象)[const char *encoding, char **buffer]

s 上的这个变体用于将 Unicode 和可转换为 Unicode 的对象编码到字符缓冲区中。 它仅适用于没有嵌入 NUL 字节的编码数据。

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

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

et(字符串、Unicode 或字符缓冲区兼容对象)[const char *encoding, char **buffer]

es 相同,除了 8 位字符串对象在不重新编码的情况下通过。 相反,实现假定字符串对象使用作为参数传入的编码。

es#(字符串、Unicode 或字符缓冲区兼容对象)[const char *encoding, char **buffer, int *buffer_length]

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

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

有两种操作模式:

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

如果 *buffer 指向一个非 NULL 指针(一个已经分配的缓冲区),PyArg_ParseTuple() 将使用这个位置作为缓冲区并解释初始值*buffer_length 作为缓冲区大小。 然后它将编码的数据复制到缓冲区中并以 NUL 终止它。 如果缓冲区不够大,则会设置 TypeError。 注意:从 Python 3.6 开始,将设置 ValueError

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

et#(字符串、Unicode 或字符缓冲区兼容对象)[const char *encoding, char **buffer, int *buffer_length]

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

b(整数)[无符号字符]

将非负 Python 整数转换为无符号小整数,存储在 C unsigned char 中。

B(整数)[无符号字符]

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

2.3 版中的新功能。

h(整数)[短整数]

将 Python 整数转换为 C short int

H(整数)[unsigned short int]

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

2.3 版中的新功能。

i(整数)[int]

将 Python 整数转换为普通的 C int

I(整数)[无符号整数]

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

2.3 版中的新功能。

l(整数)[长整数]

将 Python 整数转换为 C long int

k(整数)[unsigned long]

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

2.3 版中的新功能。

L(整数)[PY_LONG_LONG]

将 Python 整数转换为 C long long。 此格式仅在支持 long long(或 Windows 上的 _int64)的平台上可用。

K(整数)[无符号 PY_LONG_LONG]

将 Python 整数或长整数转换为 C unsigned long long 而不进行溢出检查。 此格式仅在支持 unsigned long long(或 Windows 上的 unsigned _int64)的平台上可用。

2.3 版中的新功能。

n(整数)[Py_ssize_t]

将 Python 整数或长整数转换为 C Py_ssize_t

2.5 版中的新功能。

c(长度为 1 的字符串)[字符]

将 Python 字符(表示为长度为 1 的字符串)转换为 C char

f(浮动)[浮动]

将 Python 浮点数转换为 C float

d(浮动)[双]

将 Python 浮点数转换为 C double

D(复杂)[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 函数将 Python 对象转换为 C 变量。 这需要两个参数:第一个是函数,第二个是 C 变量(任意类型)的地址,转换为 void *converter函数依次调用如下:

status = converter(object, address);

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

S(字符串)[PyStringObject *]

O 类似,但要求 Python 对象是字符串对象。 如果对象不是字符串对象,则引发 TypeError。 C 变量也可以声明为 PyObject*

U(Unicode 字符串)[PyUnicodeObject *]

O 类似,但要求 Python 对象是 Unicode 对象。 如果对象不是 Unicode 对象,则引发 TypeError。 C 变量也可以声明为 PyObject*

t#(只读字符缓冲区)[char *, int]

类似于 s#,但接受任何实现只读缓冲区接口的对象。 char*变量被设置为指向缓冲区的第一个字节,int被设置为缓冲区的长度。 只接受单段缓冲对象; TypeError 为所有其他人提升。

w(读写字符缓冲区)[char *]

类似于 s,但接受任何实现读写缓冲区接口的对象。 调用者必须通过其他方式确定缓冲区的长度,或者使用 w# 代替。 只接受单段缓冲对象; TypeError 为所有其他人提升。

w#(读写字符缓冲区)[char *, Py_ssize_t]

s# 类似,但接受任何实现读写缓冲区接口的对象。 char *变量被设置为指向缓冲区的第一个字节,Py_ssize_t被设置为缓冲区的长度。 只接受单段缓冲对象; TypeError 为所有其他人提升。

w*(面向字节的读写缓冲区)[Py_buffer]

w 之于 s* 之于 s

2.6 版中的新功能。

(items)(元组)[匹配项]

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

笔记

在 Python 1.5.2 版之前,此格式说明符只接受包含单个参数的元组,而不是任意序列。 以前导致 TypeError 在这里引发的代码现在可以毫无例外地继续进行。 对于现有代码,这预计不会成为问题。

可以在需要整数的地方传递 Python 长整数; 但是没有进行适当的范围检查——当接收字段太小而无法接收值时,最高有效位被静默截断(实际上,语义是从 C 中的向下转换继承的——你的里程可能会有所不同)。

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

|
指示 Python 参数列表中的其余参数是可选的。 对应于可选参数的 C 变量应初始化为其默认值——当未指定可选参数时,PyArg_ParseTuple() 不会触及相应 C 变量的内容。
:
格式单位列表到此结束; 冒号后的字符串用作错误消息中的函数名称(PyArg_ParseTuple() 引发的异常的“关联值”)。
;
格式单位列表到此结束; 分号后的字符串用作错误消息 而不是默认错误消息的:; 相互排斥。

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

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

要使转换成功,arg 对象必须与格式匹配且格式必须已用完。 成功时,PyArg_Parse*() 函数返回真,否则返回假并引发适当的异常。 当 PyArg_Parse*() 功能因格式单位转换失败而失败时,与该格式单位对应的地址处的变量和以下格式单位保持不变。

int PyArg_ParseTuple(PyObject *args, const char *format, ...)
解析仅将位置参数转换为局部变量的函数的参数。 成功返回真; 失败时,它返回 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[], ...)
解析将位置和关键字参数都带入局部变量的函数的参数。 成功返回真; 失败时,它返回 false 并引发适当的异常。
int PyArg_VaParseTupleAndKeywords(PyObject *args, PyObject *kw, const char *format, char *keywords[], va_list vargs)
PyArg_ParseTupleAndKeywords() 相同,除了它接受 va_list 而不是可变数量的参数。
int PyArg_Parse(PyObject *args, const char *format, ...)
用于解构“旧式”函数的参数列表的函数——这些函数使用 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未给出的可选参数对应的变量不会被填充; 这些应该由调用者初始化。 如果 args 不是元组或包含错误数量的元素,则此函数在成功时返回 true 和 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)

2.2 版中的新功能。

2.5 版更改: 此函数使用 int 类型用于 minmax。 这可能需要更改您的代码才能正确支持 64 位系统。

PyObject *Py_BuildValue(const char *format, ...)

根据类似于 PyArg_Parse*() 系列函数和值序列接受的格式字符串创建新值。 出错时返回值或NULL; 如果返回 NULL,则会引发异常。

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

当内存缓冲区作为参数传递以向构建对象提供数据时,对于 ss# 格式,将复制所需的数据。 调用者提供的缓冲区永远不会被 Py_BuildValue() 创建的对象引用。 换句话说,如果您的代码调用 malloc() 并将分配的内存传递给 Py_BuildValue(),您的代码负责为该内存调用一次 free() Py_BuildValue () 返回。

以下说明中,引用形式为格式单位; (圆)括号中的条目是格式单元将返回的 Python 对象类型; [方]括号中的条目是要传递的C值的类型。

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

s(字符串)[字符 *]

将空终止的 C 字符串转换为 Python 对象。 如果 C 字符串指针为 NULL,则使用 None

s#(字符串)[char *, int]

将 C 字符串及其长度转换为 Python 对象。 如果 C 字符串指针为 NULL,则忽略长度并返回 None

z(字符串或 None)[字符 *]

s 相同。

z#(字符串或 None)[char *, int]

s# 相同。

u(Unicode 字符串)[Py_UNICODE *]

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

u#(Unicode 字符串)[Py_UNICODE *, int]

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

i(整数)[int]

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

b(整数)[字符]

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

h(整数)[短整数]

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

l(整数)[长整数]

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

B(整数)[无符号字符]

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

H(整数)[unsigned short int]

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

I(整数/长整型)[无符号整数]

将 C unsigned int 转换为 Python 整数对象或 Python 长整数对象,如果它大于 sys.maxint

k(整数/长整型)[无符号长整型]

将 C unsigned long 转换为 Python 整数对象或 Python 长整数对象,如果它大于 sys.maxint

L(长)[PY_LONG_LONG]

将 C long long 转换为 Python 长整型对象。 仅在支持 long long 的平台上可用。

K(长)[无符号 PY_LONG_LONG]

将 C unsigned long long 转换为 Python 长整型对象。 仅在支持 unsigned long long 的平台上可用。

n (int) [Py_ssize_t]

将 C Py_ssize_t 转换为 Python 整数或长整数。

2.5 版中的新功能。

c(长度为 1 的字符串)[字符]

将表示字符的 C int 转换为长度为 1 的 Python 字符串。

d(浮动)[双]

将 C double 转换为 Python 浮点数。

f(浮动)[浮动]

d 相同。

D(复杂)[Py_complex *]

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

O(对象)[PyObject *]

原封不动地传递一个 Python 对象(除了它的引用计数,它加一)。 如果传入的对象是 NULL 指针,则假定这是因为生成参数的调用发现错误并设置异常。 因此, Py_BuildValue() 将返回 NULL 但不会引发异常。 如果尚未引发异常,则设置 SystemError

S(对象)[PyObject *]

O 相同。

N(对象)[PyObject *]

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

O&(物体)[转换器任何东西]

通过 converter 函数将 anything 转换为 Python 对象。 该函数使用 anything(应该与 void * 兼容)作为其参数调用,并且应该返回一个“新”Python 对象,如果发生错误,则返回 NULL .

(items)(元组)[匹配项]

将 C 值序列转换为具有相同项数的 Python 元组。

[items](列表)[匹配项]

将 C 值序列转换为具有相同项数的 Python 列表。

{items}(字典)[匹配项]

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

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

PyObject *Py_VaBuildValue(const char *format, va_list vargs)
Py_BuildValue() 相同,除了它接受 va_list 而不是可变数量的参数。