解析参数和构建值

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

所描述的前三个函数,PyArg_ParseTuple(),PyArg_ParseTupleAndKeywords()PyArg_Parse(),全部使用formatstrings用于告诉函数有关预期的参数。格式字符串对每个函数使用相同的语法.

解析参数

格式字符串由零个或多个“格式单元”组成。格式单元描述一个Python对象;它通常是单个字符或格式单元的括号序列。除了少数例外,没有表示序列的格式单元通常对应于单个地址参数这些函数。在以下描述中,引用的形式是格式单元;(圆形)括号中的条目是匹配格式单元的Python对象类型;并且[square]括号中的条目是应该传递其地址的Cvariable的类型.

字符串和缓冲区

这些格式允许将对象作为连续的一块内存进行访问。你不必为返回的unicode或bytesarea提供原始存储.

一般来说,当一个格式设置一个指向缓冲区的指针时,缓冲区由相应的Python对象管理,缓冲区会影响生命周期。这个对象。你不必自己释放任何记忆。唯一的例外是es, es#, etet#.

但是,当Py_buffer结构被填满时,底层缓冲区被锁定,以便调用者可以随后使用缓冲区甚至Py_BEGIN_ALLOW_THREADS阻止没有可变数据的重新调整或破坏的风险。结果,你完成数据处理后(或任何早期的中止案例)你必须打电话PyBuffer_Release() .

除非另有说明,缓冲区不是NULL-终结的.

某些格式需要一个只读的字节对象,并设置指针而不是缓冲结构。他们通过检查对象的工作来工作PyBufferProcs.bf_releasebuffer场是NULL,不允许可变物体如bytearray.

注意

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

sstr)[const char *]

将Unicode对象转换为指向字符串的C指针。指向现有字符串的指针存储在您传递其地址的字符指针变量中。C字符串是NUL终止的.Python字符串不能包含嵌入的空代码点;如果是的话,ValueError提出异常。使用"utf-8"编码。如果转换失败,请UnicodeError被养了

注意

这种格式不接受字节对象。如果你想接受文件系统路径并将它们转换为C字符串,最好使用O&格式和PyUnicode_FSConverter()作为converter.

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

s*str字节对象)[Py_buffer]
此格式接受Unicode对象以及类似字节的对象。它填充Py_buffer调用者提供的结构。在这种情况下,生成的C字符串可能包含嵌入的NUL字节。使用"utf-8"编码将//对象转换为C字符串
s#str,读取- 只有字节对象)[const char *,int或Py_ssize_t]
s*,除了它不接受可变对象。结果存储在两个C变量中,第一个是指向C字符串的指针,第二个是其长度。字符串可能包含嵌入的空字节。使用"utf-8" encoding.
zstrNone)[const char *]
将//对象转换为C字符串s,但Python对象也可能是None,在这种情况下,Cpointer设置为NULL.
z*str, 字节对象None)[Py_buffer]
s*一样,但Python对象也可能是None,在这种情况下buf成员Py_buffer结构设置为NULL.
z#str,只读字节对象None)[const char *,int]
s#一样,但Python对象也可能是None,在这种情况下,Cpointer设置为NULL.
y(只读字节对象)[const char *]

此格式转换类字节对象到指向字符串的C指针;它不接受Unicode对象。字节缓冲区不得包含嵌入的空字节;如果确实如此,则会引发ValueError异常.

在版本3.5中更改:以前,当在字节中遇到嵌入的空字节时,TypeError被引发buffer

y*字节对象)[Py_buffer]
s*上的这个变种不接受Unicode对象,类似于对象。这是接受二进制数据的推荐方法.
y#(只读字节对象)[const char *,int]
s#上的这个变种不接受Unicode对象,只有bytes-likeobjects.
Sbytes)[PyBytesObject *]
要求Python对象是bytes对象,而不试图进行任何转换。提高TypeError如果对象不是字节对象。C变量也可以声明为PyObject*.
Ybytearray)[PyByteArrayObject *]
要求Python对象是bytearray对象,而不试图进行任何转换。如果对象不是TypeError对象,则引发bytearray。C变量也可以声明为PyObject*.
ustr)[const Py_UNICODE *]

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

在版本3.5中更改:以前,当在嵌入的空代码点遇到时,TypeError被引发Python string.

自版本3.3以来删除,将在版本4.0中删除:部分旧式Py_UNICODEAPI;请迁移到使用PyUnicode_AsWideCharString().

u#str)[const Py_UNICODE *,int]

u上的这个变体存储到两个C变量中,第一个变量a指向aUnicode数据缓冲区的指针,第二个指向它的长度。这个变种允许无效的代码点.

自版本3.3以后删除,将在版本4.0中删除:部分旧式Py_UNICODE API;请迁移到使用PyUnicode_AsWideCharString().

ZstrNone)[const Py_UNICODE *]

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

自版本3.3后不推荐使用,将在版本4.0中删除:部分旧版本-style Py_UNICODE API;请迁移到使用PyUnicode_AsWideCharString().

Z#strNone)[const Py_UNICODE *,int]

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

自版本3.3后不推荐使用,将在版本4.0中删除:部分旧式的Py_UNICODE API;请迁移到使用PyUnicode_AsWideCharString().

Ustr)[PyObject *]
要求Python对象是Unicode对象,而不尝试任何转换。提高TypeError如果对象不是Unicode对象。C变量也可以声明为PyObject*.
w*(读写字节对象)[Py_buffer]
此格式接受实现读写缓冲区接口的任何对象。它填充调用者提供的Py_buffer结构。缓冲区可能包含嵌入的空字节。来电者必须致电PyBuffer_Release()用缓冲区完成时
esstr)[const char * encoding,char ** buffer]

这个变种s用于将Unicode编码为字符缓冲区。它仅适用于没有嵌入NUL字节的编码数据.

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

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

etstr, bytes要么 bytearray)[const char * encoding,char ** buffer]
与…一样 es除了传递字节字符串对象而不记录它们。相反,实现假定字节串对象使用作为参数传入的编码.
es#str)[const char * encoding,char ** buffer,int * buffer_length]

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

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

有两种操作模式:

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

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

在这两种情况下,*buffer_length设置为编码数据的长度,而不包括尾随的NUL字节.

et#str, bytesbytearray)[const char * encoding,char ** buffer,int * buffer_length]
es#相同,除了那个传递字节字符串对象而不重新编码它们。相反,实现假定字节串对象使用作为参数传入的编码.

Numbers

bint)[unsigned char]
转换a非负的Python整数到无符号的小int,存储在C unsigned char.
Bint)[unsigned char]
将Python整数转换为一个小的int而不进行溢出检查,存储在一个C unsigned char.
hint)[short int]
将一个Python整数转换为一个C short int.
Hint)[unsignedshort int]
将Python整数转换为C unsigned short int,没有overflowchecking.
iint)[int]
将Python整数转换为普通的C int.
Iint)[unsigned int]
将Python整数转换为C unsigned int,而不进行overflowchecking.
lint)[long int]
将Python整数转换为C long int.
kint)[unsigned long]
将一个Python整数转换为一个C unsigned long没有溢出检查.
Lint)[long long]
将一个Python整数转换为一个C long long.
Kint)[unsigned long long]
将Python整数转换为C unsigned long long而不进行溢出检查.
nint)[Py_ssize_t]
将Python整数转换为C Py_ssize_t.
cbytesbytearray长度为1)[char]

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

在版本3.3中更改:允许bytearray objects.

Cstr长度为1)[int]
转换一个Python字符,表示为str object of length 1,to a C int.
ffloat)[float]
将Python浮点数转换为C float.
dfloat)[double]
将Python浮点数转换为C double.
Dcomplex)[Py_complex]
将Python复数转换为C Py_complex structure.

其他对象

O(对象)[PyObject *]
在C对象指针中存储一个Python对象(没有任何转换)。因此,Cprogram接收传递的实际对象。对象的referencecount不会增加。存储的指针不是NULL.
O!(对象)[typeobject,PyObject *]
将Python对象存储在C对象指针中。这类似于O,但是有两个C参数:第一个是Python类型对象的地址,第二个是C变量的地址(类型为PyObject*),对象指针是存储。如果Python对象没有requiredtype,则TypeError被引发.
O&(object)[converter, anything]

将Python对象转换为C变量通过converter功能。这有两个参数:第一个是函数,第二个是Cvariable(任意类型)的地址,转换为void *converter函数依次调用如下:

status = converter(object, address);

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

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

在版本3.1中更改:Py_CLEANUP_SUPPORTED加入。

pbool)[int]

测试传入真值的值(布尔值 p redicate)并将结果转换为等效的C true / false整数值。如果是,则将int转换为1表达是真的0如果它是假的。这接受任何有效的Python值。参见真值检测了解Python如何测试真值的信息

新版本3.3.

(items)tuple)[matching-items]
该对象必须是Python序列,其长度是items中格式单位的数量。C参数必须对应于items。序列的格式单位可以嵌套.

可以传递“long”整数(整数值超过平台的LONG_MAX但是没有进行适当的范围检查 – 当接收字段太小而无法接收到值时,这些有效位被静默截断(实际上,语义是从Downcastsin C继承的 – 你的里程可能会有所不同).

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

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

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

版本3.3.

:
格式单位列表在此结束;冒号后的字符串用作错误消息中的函数名称(PyArg_ParseTuple()引发异常的“关联值”).
;
格式单元列表在此结束;分号后面的字符串用作默认错误消息的错误消息instead:;相互排斥.

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

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

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

API函数

int PyArg_ParseTuple PyObject  *argsconst char  *format, …
解析仅采用位置参数的局部参数的函数的参数。成功时返回true;失败时,它返回false并提出相应的异常.
int PyArg_VaParse PyObject  *argsconst char  *format,va_list  vargs
PyArg_ParseTuple()相同,只是它接受一个va_list,而不是一个可变数量的参数.
int PyArg_ParseTupleAndKeywords PyObject  *args,PyObject  *kwconst 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(),除了它接受ava_list而不是可变数量的参数.
int PyArg_ValidateKeywordArguments PyObject  *
确保关键字参数字典中的键是字符串。只有在没有使用PyArg_ParseTupleAndKeywords()的情况下才需要这个,因为已经进行了检查.

新版本3.2.

int PyArg_ParsePyObject  *args,const char  *format, …
用于解构“旧式”函数的参数列表的函数 – 这些是使用METH_OLDARGS参数parsingmethod,已在Python 3中删除。建议不要在新代码中使用参数解析,并且标准解释器中的大多数代码都已被修改为不再用于此目的。然而,它仍然是分解其他元组的一种非常方便的方式,并且可能会继续用于此目的.
int PyArg_UnpackTuple PyObject  *args,const char  *name,Py_ssize_t  min,Py_ssize_t  max, …
一种更简单的参数检索形式,它不使用格式字符串来指定参数的类型。使用此方法检索其参数的函数应声明为METH_VARARGS在函数或方法表中。包含实际参数的元组应该作为args传递;它实际上必须是一个元组。元组的长度必须至少为min且不超过max;minmax可能是平等的。必须将附加的参数传递给函数,每个函数都应该是一个指向PyObject*变量的指针;这些将填入args;它们将包含借来的参考文献。对应于args不会被填写;这些应该由调用者初始化。此函数在成功时返回true,如果args不是元组或包含错误数量的元素;如果发生故障,将设置例外.

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

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

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

sstrNone)[const char *]
转换为null终止使用str编码将C字符串转换为Python "utf-8"对象。如果C字符串指针是NULL, None使用.
s#strNone)[const char *,int]
转换一个C字符串及其长度为Python str使用"utf-8"编码的对象。如果C字符串指针是NULL,长度被忽略,None被返回.
ybytes)[const char *]
这将C字符串转换为Python bytes对象如果Cstring指针是NULL, None则返回.
y#bytes)[const char *,int]
这会将C字符串及其长度转换为Python对象。如果Cstring指针是NULL, None归来了
zstr要么 None)[const char *]
与…一样 s.
z#strNone)[const char *,int]
s#.
ustr)相同[const wchar_t *]
转换为空终止wchar_tUnicode(UTF-16或UCS-4)数据缓冲区到Python Unicode对象。如果Unicode缓冲区指针是NULL,None则返回.
u#str)[const wchar_t *,int]
将Unicode(UTF-16或UCS-4)数据缓冲区及其长度转换为PythonUnicode对象。如果Unicode缓冲区指针是NULL,则忽略长度并返回None .
UstrNone)[const char *]
s.
U#strNone)[const char *,int]
s#.
iint)[int]相同
转换一个简单的C int到一个Python整数对象.
bint)[char]
将一个简单的C char转换为一个Python整数对象.
hint)[short int]
将一个简单的C short int转换为一个Python整数对象.
lint)[longint]
将C long int转换为Python整数对象.
Bint)[unsigned char]
转换Cunsigned char到Python整数对象.
Hint)[unsigned short int]
将C unsigned short int转换为Python整数object.
Iint)[unsigned int]
将C unsigned int转换为Python整数对象.
kint)[unsigned long]
将C unsigned long转换为Python整数对象.
Lint)[long long]
将C long long转换为Python整数对象.
Kint)[unsigned long long]
转换C unsigned long long到Python整数对象.
nint)[Py_ssize_t]
将C Py_ssize_t转换为Python整数
c//(bytes长度为1)[char]
转换为C int表示一个字节到Python bytes对象的长度为1.
Cstr长度为1)[int]
转换为C int表示Python的字符str长度为1的对象.
dfloat)[double]
转换为C double一个Python浮点数.
ffloat)[float]
将C float转换为Python浮点数.
Dcomplex)[Py_complex *]
将C Py_complex结构转换为Python复数.
O(object)[PyObject *]
传递一个Python对象(引用计数除外,它由一个增加)。如果传入的对象是NULL指针,则认为这是因为产生参数的调用发现错误并设置异常。因此,Py_BuildValue()会返回NULL但是会赢得一个例外。如果还没有引发异常,SystemError isset。
S(对象)[PyObject *]
O.
N(对象)相同[PyObject *]
与…一样 O,除了它没有增加对象的引用计数。当通过调用参数列表中的对象构造函数创建对象时有用.
O&(对象)[converter, anything]
通过anything函数将converter转换为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异常isset和NULL return.

PyObject* Py_VaBuildValue const char  *format,va_list  vargs
Return value: New reference.

与…相同Py_BuildValue(),除了它接受一个va_listrather而不是一个可变数量的参数.

评论被关闭。