解析参数和构建值

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

所描述的这些函数的前三个PyArg_ParseTuple()PyArg_ParseTupleAndKeywords()PyArg_Parse()都使用* format 字符串*,用于将预期参数告知Function。格式字符串对每个函数使用相同的语法。

格式字符串由零个或多个“格式单位”组成。格式单元描述一个 Python 对象;它通常是单个字符或带括号的格式单位序列。除少数 exception,不是括号序列的格式单元通常对应于这些函数的单个地址参数。在下面的描述中,带引号的格式是格式单位;圆括号中的条目是与格式单位匹配的 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(或+19+,请参见下文)]

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

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

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

    • s#相似,此代码填充了调用者提供的 Py_buffer 结构。缓冲区被锁定,因此调用者甚至可以在Py_BEGIN_ALLOW_THREADS块内使用缓冲区;调用方负责在处理完数据后使用结构调用PyBuffer_Release

2.6 版的新Function。

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

    • 类似于s,但 Python 对象也可以是None,在这种情况下,C 指针设置为* NULL *。
  • z#(字符串,Unicode,None或任何与读取缓冲区兼容的对象)[const char *,int]

    • 这是s#,而zs
  • z*(字符串,Unicode,None或任何与缓冲区兼容的对象)[Py_buffer]

    • 这是s*,而zs

2.6 版的新Function。

  • u(Unicode)[Py_UNICODE *]

    • 将 Python Unicode 对象转换为 C 指针,该指针指向 NUL 终止的 16 位 Unicode(UTF-16)数据缓冲区。与s一样,无需为 Unicode 数据缓冲区提供存储;指向现有 Unicode 数据的指针存储在您传递其地址的Py_UNICODE指针变量中。
  • u#(Unicode)[Py_UNICODE *,整数]

    • u上的此变体将两个变量存储到 C 中,第一个变量指向 Unicode 数据缓冲区,第二个变量的长度。pass将非 Unicode 对象的读取缓冲区指针解释为指向Py_UNICODE数组的指针来处理它们。
  • es(与字符串,Unicode 或字符缓冲区兼容的对象)[const char * encoding,char ** buffer]

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

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

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

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

    • es相同,不同之处在于传递 8 位字符串对象而不重新编码它们。相反,该实现假定字符串对象使用作为参数传入的编码。
  • es#(与字符串,Unicode 或字符缓冲区兼容的对象)[const char *编码,char ** buffer,int * buffer_length]

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

它需要三个参数。第一个仅用作 Importing,并且必须是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 *编码,char ** buffer,int * buffer_length]

    • es#相同,只不过是传递字符串对象而不重新编码它们。相反,该实现假定字符串对象使用作为参数传入的编码。
  • b(整数)[unsigned char]

    • 将非负的 Python 整数转换为存储在 C unsigned char中的无符号微小 int。
  • B(整数)[unsigned char]

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

2.3 版的新Function。

  • h(整数)[short int]

    • 将 Python 整数转换为 C short int
  • H(整数)[unsigned short int]

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

2.3 版的新Function。

  • i(整数)[int]

    • 将 Python 整数转换为纯 C int
  • I(整数)[unsigned int]

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

2.3 版的新Function。

  • l(整数)[long int]

    • 将 Python 整数转换为 C long int
  • k(整数)[unsigned long]

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

2.3 版的新Function。

  • 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 版的新Function。

  • n(整数)[Py_ssize_t]

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

2.5 版的新Function。

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

    • 将以字符串 1 表示的 Python 字符转换为 C char
  • f(Float)[float]

    • 将 Python 浮点数转换为 C float
  • d(Float)[double]

    • 将 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&(对象)[转换器任何内容]

    • pass* converter *函数将 Python 对象转换为 C 变量。这有两个参数:第一个是函数,第二个是转换为void *的 C 变量(任意类型)的地址。 * 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相似,但是接受实现读写缓冲区接口的任何对象。调用者必须pass其他方式确定缓冲区的长度,或者使用w#来代替。仅接受单段缓冲区对象。 TypeError为所有其他人筹集。
  • w#(读写字符缓冲区)[char *,Py_ssize_t]

    • 类似于s#,但是接受实现读写缓冲区接口的任何对象。 char *变量设置为指向缓冲区的第一个字节,Py_ssize_t设置为缓冲区的长度。仅接受单段缓冲区对象。 TypeError为所有其他人筹集。
  • w*(面向字节的读写缓冲区)[Py_buffer]

    • 这是w s*s

2.6 版的新Function。

  • (items)(Tuples)[匹配项]

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

Note

在 Python 1.5.2 版之前,此格式说明符仅接受包含单个参数的 Tuples,而不接受任意序列。以前导致TypeError在此处引发的代码现在可以毫无 exception 地 continue 执行。对于现有代码而言,这不会成为问题。

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

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

  • |

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

    • 格式单位列表到此结束;错误消息中使用冒号后的字符串作为函数名称(PyArg_ParseTuple()引发的异常的“关联值”)。
  • ;

    • 格式单位列表到此结束;分号后的字符串用作错误消息,而不是默认错误消息。 :;相互排斥。

请注意,提供给调用方的任何 Python 对象引用都是“借用”引用;不要减少其参考计数!

传递给这些函数的其他参数必须是类型由格式字符串确定的变量的地址;这些用于存储来自 ImportingTuples 的值。如上述格式单位列表中所述,在某些情况下,这些参数将用作 Importing 值。在这种情况下,它们应与为相应格式单位指定的内容匹配。

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

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

    • 解析仅将位置参数转换为局部变量的函数的参数。成功返回 true;失败时,它返回 false 并引发适当的异常。
  • int PyArg_VaParse(PyObject *args ,const char format *,va_list * vargs *)

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

    • 解析将位置参数和关键字参数都转换为局部变量的函数的参数。成功返回 true;失败时,它返回 false 并引发适当的异常。
  • int PyArg_VaParseTupleAndKeywords(PyObject *args PyObject kw *,const char *format ,char keywords [] *,va_list * vargs *)

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

    • 用于解构“旧式”函数的参数列表的函数-这些是使用METH_OLDARGS参数解析方法的函数。不建议将其用于新代码的参数解析中,并且标准解释器中的大多数代码已被修改为不再用于此目的。但是,它仍然是分解其他 Tuples 的便捷方法,并且可以 continue 用于该目的。
  • int PyArg_UnpackTuple(PyObject *args ,const char name *,Py_ssize_t * min *,Py_ssize_t * max *,...)

    • 参数检索的一种更简单形式,它不使用格式字符串来指定参数的类型。使用此方法检索其参数的函数应在函数或方法表中语句为METH_VARARGS。包含实际参数的 Tuples 应作为* args 传递;它实际上必须是一个 Tuples。Tuples 的长度必须至少为 min 且不大于 max *; * min max 可能相等。必须将其他参数传递给函数,每个参数都应是指向PyObject*变量的指针;这些将由 args 的值填充;它们将包含借用的参考。对应于 args 没有给出的可选参数的变量将不会被填写;这些应该由调用方初始化。成功时此函数返回 true,如果 args *不是 Tuples 或包含错误数量的元素,则返回 false。如果发生故障,将设置一个 exception。

这是使用此Function的一个示例,该示例取自_weakref helper 模块的来源,以获取弱引用:

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 版中的新Function。

在版本 2.5 中更改:此函数对 *min max *使用了int类型。这可能需要更改您的代码以正确支持 64 位系统。

  • PyObject * Py_BuildValue(const char ** format *,...)
    • 返回值:新参考.

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

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

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

在下面的描述中,带引号的格式是格式单位;圆括号中的条目是格式单位将返回的 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 *]

      • 将以 NULL 终止的 Unicode(UCS-2 或 UCS-4)数据缓冲区转换为 Python Unicode 对象。如果 Unicode 缓冲区指针为* NULL *,则返回None
    • u#(Unicode 字符串)[Py_UNICODE *,整数]

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

      • 将普通 C int转换为 Python 整数对象。
    • b(整数)[char]

      • 将普通 C char转换为 Python 整数对象。
    • h(整数)[short int]

      • 将普通 C short int转换为 Python 整数对象。
    • l(整数)[long int]

      • 将 C long int转换为 Python 整数对象。
    • B(整数)[unsigned char]

      • 将 C unsigned char转换为 Python 整数对象。
    • H(整数)[unsigned short int]

      • 将 C unsigned short int转换为 Python 整数对象。
    • I(整数/长整数)[unsigned int]

      • 如果 C unsigned int大于sys.maxint,则将其转换为 Python 整数对象或 Python 长整数对象。
    • k(整数/长整数)[unsigned long]

      • 如果 C unsigned long大于sys.maxint,则将其转换为 Python 整数对象或 Python 长整数对象。
    • 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 版的新Function。

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

    • 将代表字符的 C int转换为长度为 1 的 Python 字符串。
  • d(Float)[double]

    • 将 C double转换为 Python 浮点数。
  • f(Float)[float]

    • d相同。
  • D(复杂)[Py_complex *]

    • 将 C Py_complex结构转换为 Python 复数。
  • O(对象)[PyObject *]

    • 传递一个不变的 Python 对象(除了引用计数,该计数增加一)。如果传入的对象是* NULL 指针,则认为这是由于产生该参数的调用发现错误并设置异常而引起的。因此,Py_BuildValue()将返回 NULL *,但不会引发异常。如果尚未引发任何异常,则设置SystemError
  • S(对象)[PyObject *]

    • O相同。
  • N(对象)[PyObject *]

    • O相同,不同之处在于它不会增加对象的引用计数。当pass调用参数列表中的对象构造函数创建对象时很有用。
  • O&(对象)[转换器任何内容]

    • pass* converter 函数将 anything 转换为 Python 对象。该函数以 anything (应与void *兼容)作为参数调用,并应返回“新” Python 对象,如果发生错误,则返回 NULL *。
  • (items)(Tuples)[匹配项]

    • 将具有相同数量项的 C 值序列转换为 PythonTuples。
  • [items](列表)[匹配项]

    • 将 C 值序列转换为具有相同数量项的 Python 列表。
  • {items}(字典)[匹配项]

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

如果格式字符串中有错误,则设置SystemErrorexception,并返回* NULL *。

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