解析参数并构建值变量

在创建你自己的扩展函数和方法时,这些函数是有用的。其它的信息和样例见 扩展和嵌入 Python 解释器

这些函数描述的前三个,PyArg_ParseTuple()PyArg_ParseTupleAndKeywords(),以及 PyArg_Parse(),它们都使用 格式化字符串 来将函数期待的参数告知函数。这些函数都使用相同语法规则的格式化字符串。

解析参数

一个格式化字符串包含 0 或者更多的格式单元。一个格式单元用来描述一个 Python 对象;它通常是一个字符或者由括号括起来的格式单元序列。除了少数例外,一个非括号序列的格式单元通常对应这些函数的具有单一地址的参数。在接下来的描述中,双引号内的表达式是格式单元;圆括号 () 内的是对应这个格式单元的 Python 对象类型;方括号 [] 内的是传递的 C 变量(变量集)类型。

字符串和缓存区

这些格式允许将对象按照连续的内存块形式进行访问。你没必要提供返回的 unicode 字符或者字节区的原始数据存储。

一般的,当一个表达式设置一个指针指向一个缓冲区,这个缓冲区可以被相应的 Python 对象管理,并且这个缓冲区共享这个对象的生存周期。你不需要人为的释放任何内存空间。除了这些 es, es#, et and et#.

然而,当一个 Py_buffer 结构被赋值,其包含的缓冲区被锁住,所以调用者在随后使用这个缓冲区,即使在 Py_BEGIN_ALLOW_THREADS 块中,可以避免可变数据因为调整大小或者被销毁所带来的风险。因此,你不得不调用 PyBuffer_Release() 在你结束数据的处理时(或者在之前任何中断事件中)

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

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

备注

对于所有 # 格式的变体(s#y# 等),宏 PY_SSIZE_T_CLEAN 必须在包含 Python 之前定义。 h。在 Python 3.9 及更早版本上,如果定义了 PY_SSIZE_T_CLEAN 宏,则长度参数的类型为 Py_ssize_t,否则为 int。

s (str) [const char *]

将一个 Unicode 对象转换成一个指向字符串的 C 指针。一个指针指向一个已经存在的字符串,这个字符串存储的是传如的字符指针变量。C 字符串是已空结束的。Python 字符串不能包含嵌入的无效的代码点;如果由,一个 ValueError 异常会被引发。Unicode 对象被转化成 'utf-8' 编码的 C 字符串。如果转换失败,一个 UnicodeError 异常被引发。

备注

这个表达式不接受 bytes-like objects。如果你想接受文件系统路径并将它们转化成 C 字符串,建议使用 O& 表达式配合 PyUnicode_FSConverter() 作为 转化函数

在 3.5 版更改: 以前,当 Python 字符串中遇到了嵌入的 null 代码点会引发 TypeError

s* (str or bytes-like object) [Py_buffer]

这个表达式既接受 Unicode 对象也接受类字节类型对象。它为由调用者提供的 Py_buffer 结构赋值。这里结果的 C 字符串可能包含嵌入的 NUL 字节。Unicode 对象通过 'utf-8' 编码转化成 C 字符串。

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

s*,除了它不接受易变的对象。结果存储在两个 C 变量中,第一个是指向 C 字符串的指针,第二个是它的长度。字符串可能包含嵌入的 null 字节。Unicode 对象都被通过 'utf-8' 编码转化成 C 字符串。

z (str or None) [const char *]

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

z* (str, bytes-like object or None) [Py_buffer]

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

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

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

y (read-only bytes-like object) [const char *]

这个表达式将一个类字节类型对象转化成一个指向字符串的 C 指针;它不接受 Unicode 对象。字节缓存区必须不包含嵌入的 null 字节;如果包含了 null 字节,会引发一个 ValueError 异常。

在 3.5 版更改: 以前,当字节缓冲区中遇到了嵌入的 null 字节会引发 TypeError

y* (bytes-like object) [Py_buffer]

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

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

s# 的变式,不接受 Unicode 对象,只接受类字节类型变量。

S (bytes) [PyBytesObject *]

Requires that the Python object is a bytes object, without attempting any conversion. Raises TypeError if the object is not a bytes object. The C variable may also be declared as PyObject*.

Y (bytearray) [PyByteArrayObject *]

Requires that the Python object is a bytearray object, without attempting any conversion. Raises TypeError if the object is not a bytearray object. The C variable may also be declared as PyObject*.

u (str) [const Py_UNICODE *]

将一个 Python Unicode 对象转化成指向一个以空终止的 Unicode 字符缓冲区的指针。你必须传入一个 Py_UNICODE 指针变量的地址,存储了一个指向已经存在的 Unicode 缓冲区的指针。请注意一个 Py_UNICODE 类型的字符宽度取决于编译选项(16 位或者 32 位)。Python 字符串必须不能包含嵌入的 null 代码点;如果有,引发一个 ValueError 异常。

在 3.5 版更改: 以前,当 Python 字符串中遇到了嵌入的 null 代码点会引发 TypeError

从版本 3.3 开始标记为过时,将在版本 3.12 中移除。: 这是旧版样式 Py_UNICODE API; 请迁移至 PyUnicode_AsWideCharString().

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

u 的变式,存储两个 C 变量,第一个指针指向一个 Unicode 数据缓存区,第二个是它的长度。它允许 null 代码点。

从版本 3.3 开始标记为过时,将在版本 3.12 中移除。: 这是旧版样式 Py_UNICODE API; 请迁移至 PyUnicode_AsWideCharString().

Z (strNone) [const Py_UNICODE *]

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

从版本 3.3 开始标记为过时,将在版本 3.12 中移除。: 这是旧版样式 Py_UNICODE API; 请迁移至 PyUnicode_AsWideCharString().

Z# (strNone) [const Py_UNICODE *, Py_ssize_t]

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

从版本 3.3 开始标记为过时,将在版本 3.12 中移除。: 这是旧版样式 Py_UNICODE API; 请迁移至 PyUnicode_AsWideCharString().

U (str) [PyObject *]

Requires that the Python object is a Unicode object, without attempting any conversion. Raises TypeError if the object is not a Unicode object. The C variable may also be declared as PyObject*.

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

这个表达式接受任何实现可读写缓存区接口的对象。它为调用者提供的 Py_buffer 结构赋值。缓冲区可能存在嵌入的 null 字节。当缓冲区使用完后调用者需要调用 PyBuffer_Release()

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

s 的变式,它将编码后的 Unicode 字符存入字符缓冲区。它只处理没有嵌 NUL 字节的已编码数据。

This format requires two arguments. The first is only used as input, and must be a const char* which points to the name of an encoding as a NUL-terminated string, or NULL, in which case 'utf-8' encoding is used. An exception is raised if the named encoding is not known to Python. The second argument must be a char**; the value of the pointer it references will be set to a buffer with the contents of the argument text. The text will be encoded in the encoding specified by the first argument.

PyArg_ParseTuple() 会分配一个足够大小的缓冲区,将编码后的数据拷贝进这个缓冲区并且设置 \buffer* 引用这个新分配的内存空间。调用者有责任在使用后调用 PyMem_Free() 去释放已经分配的缓冲区。

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

es 相同,除了不用重编码传入的字符串对象。相反,它假设传入的参数是编码后的字符串类型。

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

s# 的变式,它将已编码的 Unicode 字符存入字符缓冲区。不像 es 表达式,它允许传入的数据包含 NUL 字符。

It requires three arguments. The first is only used as input, and must be a const char* which points to the name of an encoding as a NUL-terminated string, or NULL, in which case 'utf-8' encoding is used. An exception is raised if the named encoding is not known to Python. The second argument must be a char**; the value of the pointer it references will be set to a buffer with the contents of the argument text. The text will be encoded in the encoding specified by the first argument. The third argument must be a pointer to an integer; the referenced integer will be set to the number of bytes in the output buffer.

有两种操作方式:

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

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

在这两个例子中,\buffer_length* 被设置为编码后结尾不为 NUL 的数据的长度。

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

es# 相同,除了不用重编码传入的字符串对象。相反,它假设传入的参数是编码后的字符串类型。

数字

b (int) [unsigned char]

Convert a nonnegative Python integer to an unsigned tiny int, stored in a C unsigned char.

B (int) [unsigned char]

Convert a Python integer to a tiny int without overflow checking, stored in a C unsigned char.

h (int) [short int]

Convert a Python integer to a C short int.

H (int) [unsigned short int]

Convert a Python integer to a C unsigned short int, without overflow checking.

i (int) [int]

Convert a Python integer to a plain C int.

I (int) [unsigned int]

Convert a Python integer to a C unsigned int, without overflow checking.

l (int) [long int]

Convert a Python integer to a C long int.

k (int) [unsigned long]

Convert a Python integer to a C unsigned long without overflow checking.

L (int) [long long]

Convert a Python integer to a C long long.

K (int) [unsigned long long]

Convert a Python integer to a C unsigned long long without overflow checking.

n (int) [Py_ssize_t]

将一个 Python 整型转化成一个 C Py_ssize_t Python 元大小类型。

c (bytes 或者 bytearray 长度为 1) [char]

Convert a Python byte, represented as a bytes or bytearray object of length 1, to a C char.

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

C (str 长度为 1) [int]

Convert a Python character, represented as a str object of length 1, to a C int.

f (float) [float]

Convert a Python floating point number to a C float.

d (float) [double]

Convert a Python floating point number to a C double.

D (complex) [Py_complex]

将一个 Python 复数类型转化成一个 C Py_complex Python 复数类型。

其他对象

O (object) [PyObject *]

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

O! (object) [typeobject, PyObject *]

Store a Python object in a C object pointer. This is similar to O, but takes two C arguments: the first is the address of a Python type object, the second is the address of the C variable (of type PyObject*) into which the object pointer is stored. If the Python object does not have the required type, TypeError is raised.

O& (object) [converter, anything]

Convert a Python object to a C variable through a converter function. This takes two arguments: the first is a function, the second is the address of a C variable (of arbitrary type), converted to void*. The converter function in turn is called as follows:

  1. status = converter(object, address);

where object is the Python object to be converted and address is the void* argument that was passed to the PyArg_Parse* function. The returned status should be 1 for a successful conversion and 0 if the conversion has failed. When the conversion fails, the converter function should raise an exception and leave the content of address unmodified.

如果 converter 返回 Py_CLEANUP_SUPPORTED,则如果参数解析最终失败,它可能会再次调用该函数,从而使转换器有机会释放已分配的任何内存。在第二个调用中,object 参数将为 NULL;因此,该参数将为 NULL;因此,该参数将为 NULL,因此,该参数将为 NULL``(如果值)为 ``NULL address 的值与原始呼叫中的值相同。

在 3.1 版更改: Py_CLEANUP_SUPPORTED 被添加。

p (bool) [int]

测试传入的值是否为真(一个布尔判断)并且将结果转化为相对应的 C true/false 整型值。如果表达式为真置 1,假则置 0。它接受任何合法的 Python 值。参见 逻辑值检测 获取更多关于 Python 如何测试值为真的信息。

3.3 新版功能.

(items) (tuple) [matching-items]

对象必须是 Python 序列,它的长度是 items 中格式单元的数量。C 参数必须对应 items 中每一个独立的格式单元。序列中的格式单元可能有嵌套。

传递 “long” 整型(整型的值超过了平台的 LONG_MAX 限制)是可能的,然而没有进行适当的范围检测——当接收字段太小而接收不到值时,最重要的位被静默地截断(实际上,C 语言会在语义继承的基础上强制类型转换——期望的值可能会发生变化)。

格式化字符串中还有一些其他的字符具有特殊的涵义。这些可能并不嵌套在圆括号中。它们是:

|

表明在 Python 参数列表中剩下的参数都是可选的。C 变量对应的可选参数需要初始化为默认值——当一个可选参数没有指定时, PyArg_ParseTuple() 不能访问相应的 C 变量(变量集)的内容。

$

PyArg_ParseTupleAndKeywords() only:表明在 Python 参数列表中剩下的参数都是强制关键字参数。当前,所有强制关键字参数都必须也是可选参数,所以格式化字符串中 | 必须一直在 $ 前面。

3.3 新版功能.

:

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

;

格式单元的列表结束标志;分号后的字符串被用来作为错误消息取代默认的错误消息。 :; 相互排斥。

注意任何由调用者提供的 Python 对象引用是 借来的 引用;不要递减它们的引用计数!

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

For the conversion to succeed, the arg object must match the format and the format must be exhausted. On success, the PyArg_Parse* functions return true, otherwise they return false and raise an appropriate exception. When the PyArg_Parse* functions fail due to conversion failure in one of the format units, the variables at the addresses corresponding to that and the following format units are left untouched.

API 函数

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

Part of the Stable ABI.

解析一个函数的参数,表达式中的参数按参数位置顺序存入局部变量中。成功返回 true;失败返回 false 并且引发相应的异常。

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

Part of the Stable ABI.

PyArg_ParseTuple() 相同,然而它接受一个 va_list 类型的参数而不是可变数量的参数集。

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

Part of the Stable ABI.

分析将位置参数和关键字参数同时转换为局部变量的函数的参数。 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)

Part of the Stable ABI.

PyArg_ParseTupleAndKeywords() 相同,然而它接受一个va_list类型的参数而不是可变数量的参数集。

int PyArg_ValidateKeywordArguments(PyObject*)

Part of the Stable ABI.

确保字典中的关键字参数都是字符串。这个函数只被使用于 PyArg_ParseTupleAndKeywords() 不被使用的情况下,后者已经不再做这样的检查。

3.2 新版功能.

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

Part of the Stable ABI.

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

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

Part of the Stable ABI.

A simpler form of parameter retrieval which does not use a format string to specify the types of the arguments. Functions which use this method to retrieve their parameters should be declared as METH_VARARGS in function or method tables. The tuple containing the actual parameters should be passed as args; it must actually be a tuple. The length of the tuple must be at least min and no more than max; min and max may be equal. Additional arguments must be passed to the function, each of which should be a pointer to a PyObject* variable; these will be filled in with the values from args; they will contain borrowed references. The variables which correspond to optional parameters not given by args will not be filled in; these should be initialized by the caller. This function returns true on success and false if args is not a tuple or contains the wrong number of elements; an exception will be set if there was a failure.

这是一个使用此函数的示例,取自 _weakref 帮助模块用来弱化引用的源代码:

  1. static PyObject *
  2. weakref_ref(PyObject *self, PyObject *args)
  3. {
  4. PyObject *object;
  5. PyObject *callback = NULL;
  6. PyObject *result = NULL;
  7. if (PyArg_UnpackTuple(args, "ref", 1, 2, &object, &callback)) {
  8. result = PyWeakref_NewRef(object, callback);
  9. }
  10. return result;
  11. }

这个例子中调用 PyArg_UnpackTuple() 完全等价于调用 PyArg_ParseTuple():

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

创建变量

PyObject *Py_BuildValue(const char *format, …)

Return value: New reference. Part of the Stable ABI.

Create a new value based on a format string similar to those accepted by the PyArg_Parse* family of functions and a sequence of values. Returns the value or NULL in the case of an error; an exception will be raised if NULL is returned.

Py_BuildValue() 并不一直创建一个元组。只有当它的格式化字符串包含两个或更多的格式单元才会创建一个元组。如果格式化字符串是空,它返回 None;如果它包含一个格式单元,它返回由格式单元描述的的任一对象。用圆括号包裹格式化字符串可以强制它返回一个大小为 0 或者 1 的元组。

当内存缓存区的数据以参数形式传递用来构建对象时,如 ss# 格式单元,会拷贝需要的数据。调用者提供的缓冲区从来都不会被由 Py_BuildValue() 创建的对象来引用。换句话说,如果你的代码调用 malloc() 并且将分配的内存空间传递给 Py_BuildValue(),你的代码就有责任在 Py_BuildValue() 返回时调用 free()

在下面的描述中,双引号的表达式使格式单元;圆括号 () 内的是格式单元将要返回的 Python 对象类型;方括号 [] 内的是传递的 C 变量(变量集)的类型。

字符例如空格,制表符,冒号和逗号在格式化字符串中会被忽略(但是不包括格式单元,如 s#)。这可以使很长的格式化字符串具有更好的可读性。

  • s (strNone) [const char *]

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

    s# (strNone) [const char *, Py_ssize_t]

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

    y (bytes) [const char *]

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

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

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

    z (str or None) [const char *]

    s 一样。

    z# (strNone) [const char *, Py_ssize_t]

    s# 一样。

    u (str) [const wchar_t *]

    Convert a null-terminated wchar_t buffer of Unicode (UTF-16 or UCS-4) data to a Python Unicode object. If the Unicode buffer pointer is NULL, None is returned.

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

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

    U (strNone) [const char *]

    s 一样。

    U# (strNone) [const char *, Py_ssize_t]

    s# 一样。

    i (int) [int]

    Convert a plain C int to a Python integer object.

    b (int) [char]

    Convert a plain C char to a Python integer object.

    h (int) [short int]

    Convert a plain C short int to a Python integer object.

    l (int) [long int]

    Convert a C long int to a Python integer object.

    B (int) [unsigned char]

    Convert a C unsigned char to a Python integer object.

    H (int) [unsigned short int]

    Convert a C unsigned short int to a Python integer object.

    I (int) [unsigned int]

    Convert a C unsigned int to a Python integer object.

    k (int) [unsigned long]

    Convert a C unsigned long to a Python integer object.

    L (int) [long long]

    Convert a C long long to a Python integer object.

    K (int) [unsigned long long]

    Convert a C unsigned long long to a Python integer object.

    n (int) [Py_ssize_t]

    将一个 C Py_ssize_t 类型转化为 Python 整型。

    c (bytes 长度为1 ) [char]

    Convert a C int representing a byte to a Python bytes object of length 1.

    C (str 长度为 1) [int]

    Convert a C int representing a character to Python str object of length 1.

    d (float) [double]

    Convert a C double to a Python floating point number.

    f (float) [float]

    Convert a C float to a Python floating point number.

    D (complex) [Py_complex *]

    将一个 C Py_complex 类型的结构转化为 Python 复数类型。

    O (object) [PyObject *]

    将 Python 对象传递不变(其引用计数除外,该计数由 1 递增)。 如果传入的对象是 NULL 指针,则假定这是由于生成参数的调用发现错误并设置异常而引起的。因此,Py_BuildValue() 将返回 NULL,但不会引发异常。 如果尚未引发异常,则设置 SystemError

    S (object) [PyObject *]

    O 相同。

    N (object) [PyObject *]

    O 相同,然而它并不增加对象的引用计数。当通过调用参数列表中的对象构造器创建对象时很实用。

    O& (object) [converter, anything]

    Convert anything to a Python object through a converter function. The function is called with anything (which should be compatible with void*) as its argument and should return a “new” Python object, or NULL if an error occurred.

    (items) (tuple) [matching-items]

    将一个 C 变量序列转换成 Python 元组并保持相同的元素数量。

    [items] (list) [相关的元素]

    将一个 C 变量序列转换成 Python 列表并保持相同的元素数量。

    {items} (dict) [相关的元素]

    将一个C变量序列转换成 Python 字典。每一对连续的 C 变量对作为一个元素插入字典中,分别作为关键字和值。

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

PyObject *Py_VaBuildValue(const char *format, va_list vargs)

Return value: New reference. Part of the Stable ABI.

Py_BuildValue() 相同,然而它接受一个 va_list 类型的参数而不是可变数量的参数集。