语句解释及变量编译

这些函数在创建你自己的函数时帮助很大。更多说明以及实例可参考说明文档中的 扩展和嵌入 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)在包含 Python.h 头文件之前由 PY_SSIZE_T_CLEAN 宏的定义控制。如果这个宏被定义,长度是一个 Py_ssize_t Python元大小类型而不是一个 int 整型。在未来的Python版本中将会改变,只支持 Py_ssize_t 而放弃支持 int 整型。最好一直定义 PY_SSIZE_T_CLEAN 这个宏。

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, 只读 bytes-like object) [const char *, int or 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, 只读 bytes-like object or None) [const char *, int]

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

This variant on s# doesn't accept Unicode objects, only bytes-like objects.

S (bytes) [PyBytesObject *]

要求Python对象是一个 bytes 类型对象,没有尝试任何的转换。如果不是一个字节类型对象会引发 TypeError 异常。C变量也可能声明为 PyObject* 类型。

Y (bytearray) [PyByteArrayObject *]

要求Python对象是一个 bytearray 类型对象,没有尝试任何的转换。如果不是一个 bytearray 类型对象会引发 TypeError 异常。C变量也可能声明为 PyObject* 类型。

u (str) [const Py_UNICODE *]

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

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

Deprecated since version 3.3, will be removed in version 4.0: 这是旧版样式 Py_UNICODE API; 请迁移至 PyUnicode_AsWideCharString().

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

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

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# (strNone) [const Py_UNICODE *, int]

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对象,没有尝试任何的转换。如果不是一个Unicode对象会引发 TypeError 异常。C变量也可能声明为 PyObject* 类型。

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

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

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

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

这个表达式需要两个参数。第一个仅用于传入,并且必须是一个 const char* 指向一个 'utf-8' 编码的以空终止或者 NULL 的字符串名称。如果Python不识别名字的编码方式会引发一个异常。第二个参数必须是一个 char**;指针指向一个包含了参数文本内容的缓存区。文本将被第一个参数指定的编码格式编码。

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

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

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

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

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

它需要三个参数。第一个仅用于传入,并且必须是一个 const char* 指向一个 'utf-8' 编码的以空终止或者 NULL 的字符串名称。如果Python不识别名字的编码方式会引发一个异常。第二个参数必须是一个 char**;指针指向一个包含了参数文本内容的缓存区。文本将被第一个参数指定的编码格式编码。第三个参数必须是一个整型指针;指针引用的值用来设定输出缓冲区的字节数量。

有两种操作方式:

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

如果 *buffer 指向一个非 NULL 的指针(一个已经分配内存的缓冲区), PyArg_ParseTuple() 将使用这个地址作为缓冲区并且将 *buffer_length 初始化的值理解为缓冲区的大小。然后它将编码后的数据拷贝到缓冲区并以空终止。如果这个缓冲区并不是足够大,一个 TypeError 会被设置。

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

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

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

数字

b (int) [unsigned char]

将一个非负的Python整型转化成一个无符号的微整型,存储在一个C unsigned char 类型中。

B (int) [unsigned char]

将一个Python整型转化成一个微整型并不检查溢出问题,存储在一个C unsigned char 类型中。

h (int) [short int]

将一个Python整型转化成一个C short int 短整型。

H (int) [unsigned short int]

将一个Python整型转化成一个C unsigned short int 无符号短整型,并不检查溢出问题。

i (int) [int]

将一个Python整型转化成一个C int 整型。

I (int) [unsigned int]

将一个Python整型转化成一个C unsigned int 无符号整型,并不检查溢出问题。

l (int) [long int]

将一个Python整型转化成一个C long int 长整型。

k (int) [unsigned long]

将一个Python整型转化成一个C unsigned long int 无符号长整型,并不检查溢出问题。

L (int) [long long]

将一个Python整型转化成一个C long long 长长整型。

K (int) [unsigned long long]

将一个Python整型转化成一个C unsigned long long 无符号长长整型,并不检查溢出问题。

n (int) [Py_ssize_t]

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

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

将一个Python字节类型,如一个长度为1的 bytes 或者 bytearray 对象,转化成一个C char 字符类型。

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

C (str 长度为1) [int]

将一个Python字符,如一个长度为1的 str 字符串对象,转化成一个C int 整型类型。

f (float) [float]

将一个Python浮点数转化成一个C float 浮点数。

d (float) [double]

将一个Python浮点数转化成一个C double 双精度浮点数。

D (complex) [Py_complex]

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

其他对象

O (object) [PyObject *]

用一个C的对象指针存储一个Python对象(没有任何格式转换)。这样传递给C程序的是实际的对象。这个对象的引用计数不会增加。这个指针存储的不是 NULL

O! (object) [typeobject, PyObject *]

将一个Python对象存入一个C指针。和 O 类似,但是需要两个C参数:第一个是Python类型对象的地址,第二个是存储对象指针的C变量( PyObject* 变量)的地址。如果Python对象类型不对,会抛出 TypeError 异常。

O& (object) [converter, anything]

通过一个 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 被添加。

p (bool) [int]

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

3.3 新版功能.

(items) (tuple) [matching-items]

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

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

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

|

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

$

PyArg_ParseTupleAndKeywords() only:表明在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_list类型的参数而不是可变数量的参数集。

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

解析一个函数的参数,关键字参数和表达式中的参数按参数位置顺序存入局部变量中。其中*keywords*参数是一个以空结束的数组,存放关键字参数的名称。空的名称表示为 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_list类型的参数而不是可变数量的参数集。

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 的值;它们将包含借来的引用。不在 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#)。这可以使很长的格式化字符串具有更好的可读性。

s (strNone) [const char *]

使用 'utf-8' 编码将一个C以空结束的字符串转化成Python str 字符串对象。如果这个C字符串指针是 NULL ,返回 None

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

使用 'utf-8' 编码将一个C字符串和其长度转化成Python str 字符串对象。如果这个C字符串指针是 NULL ,长度会被忽略并且返回 None

y (bytes) [const char *]

它将一个C字符串和其长度转化成一个Python bytes 字节类型对象。如果这个C字符串指针是 NULL,返回``None``

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

它将一个C字符串和其长度转化成一个Python对象。如果这个C字符串指针是 NULL,返回``None``。

z (str or None) [const char *]

和``s``一样。

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

和``s#``一样。

u (str) [const wchar_t *]

将一个以 null 结束的 wchar_t Unicode (UTF-16 或 UCS-4) 数据缓冲区转换为一个 Python Unicode 对象。如果 Unicode 缓冲区指针为 NULL 则返回 None

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

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

U (strNone) [const char *]

和``s``一样。

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

和``s#``一样。

i (int) [int]

将一个C int 整型转化成Python整型对象。

b (int) [char]

将一个C char 字符型转化成Python整型对象。

h (int) [short int]

将一个C short int 短整型转化成Python整型对象。

l (int) [long int]

将一个C long int 长整型转化成Python整型对象。

B (int) [unsigned char]

将一个C unsigned char 无符号字符型转化成Python整型对象。

H (int) [unsigned short int]

将一个C unsigned long 无符号短整型转化成Python整型对象。

I (int) [unsigned int]

将一个C unsigned long 无符号整型转化成Python整型对象。

k (int) [unsigned long]

将一个C unsigned long 无符号长整型转化成Python整型对象。

L (int) [long long]

将一个C long long 长长整形转化成Python整形对象。

K (int) [unsigned long long]

将一个C unsigned long long 无符号长长整型转化成Python整型对象。

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) [double]

将一个C double 双精度浮点数转化为Python浮点数类型数字。

f (float) [float]

将一个C float 单精度浮点数转化为Python浮点数类型数字。

D (复数) [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]

通过 converter 函数将 任何类型的变量*转化为一个Python对象。这个函数调用 *任何类型的变量 (这个类型可以被 void * 兼容) 作为它的参数,并且应该返回一个"新的"Python对象,或者 NULL 如果有错误产生。

(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.

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