Parsing arguments and building values¶
这些函数在创建自己的扩展函数和方法时很有用。有关其他信息和示例,请参见Extending and Embedding the Python Interpreter。
The first three of these functions described, PyArg_ParseTuple()
, PyArg_ParseTupleAndKeywords()
, and PyArg_Parse()
, all use format strings which are used to tell the function about the expected arguments. 格式字符串对这些函数使用相同的语法。
Parsing arguments¶
格式字符串由零个或多个“格式单元”组成。格式单元描述一个Python对象;它通常是单个字符或格式单元的括号序列。除了少数例外,不是括号序列的格式单元通常对应于这些函数的单个地址参数。在下面的描述中,引用的形式是格式单元; (圆括号)中的条目是与格式单元匹配的Python对象类型;并且[方括号]中的条目是其地址应被传递的C变量的类型。
Strings and buffers¶
这些格式允许将对象作为连续的内存块访问。您不必为返回的unicode或bytes区域提供原始存储。
通常,当格式设置指向缓冲区的指针时,缓冲区由相应的Python对象管理,缓冲区共享此对象的生存期。你不必自己释放任何内存。唯一的例外是es
,es#
,et
和et#
。
但是,当Py_buffer
结构被填充时,底层缓冲区被锁定,这样调用者即使在Py_BEGIN_ALLOW_THREADS
块内也可以使用缓冲区,而不会调整可变数据的大小或销毁。因此,在完成数据处理(或任何早期异常终止的情况)后,必须调用 PyBuffer_Release()
。
除非另有说明,缓冲液不是NUL-终止的。
某些格式需要只读bytes-like object,并设置指针而不是缓冲区结构。它们通过检查对象的PyBufferProcs.bf_releasebuffer
字段是否为NULL来工作,该对象禁止诸如bytearray
之类的可变对象。
注意
对于所有#
格式变体(s#
,y#
等)),通过在包括Python.h
之前定义宏PY_SSIZE_T_CLEAN
来控制长度参数的类型(int或Py_ssize_t
)。如果定义了宏,则长度为Py_ssize_t
,而不是int
。在将来的Python版本中,这种行为将会改变,只支持Py_ssize_t
并且删除int
支持。最好始终定义PY_SSIZE_T_CLEAN
。
s
(str
)[const char *]将Unicode对象转换为指向字符串的C指针。指向现有字符串的指针存储在您传递的地址的字符指针变量中。C字符串是NUL终止的。Python字符串不能包含嵌入的空代码点;如果是,则会引发
ValueError
异常。使用'utf-8'
编码将Unicode对象转换为C字符串。如果此转换失败,则会引发UnicodeError
。注意
此格式不接受bytes-like objects。如果要接受文件系统路径并将其转换为C字符串,则最好使用
PyUnicode_FSConverter()
的O&
格式为转换器 t5 >。在版本3.5中更改:以前,在Python字符串中遇到嵌入的空代码点时,引发了
TypeError
。s*
(str
或bytes-like object)[Py_buffer]- 此格式接受Unicode对象以及类似字节的对象。它填充由调用者提供的
Py_buffer
结构。在这种情况下,所得到的C字符串可以包含嵌入的NUL字节。使用'utf-8'
编码将Unicode对象转换为C字符串。 s#
(str
,只读bytes-like object)[const char *,int或Py_ssize_t
]- 像
s*
,除了它不接受可变对象。结果存储到两个C变量中,第一个是指向C字符串的指针,第二个是它的长度。该字符串可以包含嵌入的空字节。使用'utf-8'
编码将Unicode对象转换为C字符串。 z
(str
或None
)[const char *]- 像
s
,但Python对象也可以是None
,在这种情况下,C指针设置为NULL。 z*
(str
,bytes-like object或None
)[Py_buffer]- Like
s*
, but the Python object may also beNone
, in which case thebuf
member of thePy_buffer
structure is set to NULL. z#
(str
,只读bytes-like object或None
)[const char *,int]- 像
s#
,但是Python对象也可以是None
,在这种情况下,C指针设置为NULL。 y
(只读bytes-like object)[const char *]这种格式将类似字节的对象转换为指向字符串的C指针;它不接受Unicode对象。字节缓冲区不能包含嵌入的空字节;如果是,则会引发
ValueError
异常。在版本3.5中更改:以前,在字节缓冲区中遇到嵌入的空字节时,引发了
TypeError
。y*
(bytes-like object)[Py_buffer]- 在
s*
上的此变体不接受Unicode对象,只接受字节状对象。这是接受二进制数据的推荐方法。 y#
(只读bytes-like object)[const char *,int]- 在
s#
上的此变体不接受Unicode对象,只接受字节状对象。 S
(bytes
)[PyBytesObject *]- 需要Python对象是
bytes
对象,而不尝试任何转换。如果对象不是字节对象,则引发TypeError
。C变量也可以被声明为PyObject*
。 Y
(bytearray
)[PyByteArrayObject *]- 需要Python对象是
bytearray
对象,而不尝试任何转换。如果对象不是bytearray
对象,则引发TypeError
。C变量也可以被声明为PyObject*
。 u
(str
)[Py_UNICODE *]将Python Unicode对象转换为C指针,指向NUL终止的Unicode字符缓冲区。您必须传递
Py_UNICODE
指针变量的地址,该变量将使用指向现有Unicode缓冲区的指针填充。请注意,Py_UNICODE
字符的宽度取决于编译选项(它是16位或32位)。Python字符串不能包含嵌入的空代码点;如果是,则会引发ValueError
异常。在版本3.5中更改:以前,在Python字符串中遇到嵌入的空代码点时,引发了
TypeError
。u#
(str
)[Py_UNICODE *,int]- 在
u
上的这个变体存储到两个C变量中,第一个是指向Unicode数据缓冲区的指针,第二个是它的长度。此变体允许空代码点。 Z
(str
或None
)[Py_UNICODE *]- 像
u
,但是Python对象也可以是None
,在这种情况下,Py_UNICODE
指针设置为NULL 。 Z#
(str
或None
)[Py_UNICODE *,int]- 像
u#
,但是Python对象也可以是None
,在这种情况下,Py_UNICODE
指针设置为NULL t7 >。 U
(str
)[PyObject *]- 需要Python对象是Unicode对象,而不尝试任何转换。如果对象不是Unicode对象,则引发
TypeError
。C变量也可以被声明为PyObject*
。 w*
(读写bytes-like object)[Py_buffer]- 此格式接受实现读写缓冲器接口的任何对象。它填充由调用者提供的
Py_buffer
结构。缓冲器可以包含嵌入的空字节。调用者在缓冲区完成后必须调用PyBuffer_Release()
。 es
(str
)[const char * encoding,char ** buffer]在
s
上的此变体用于将Unicode编码为字符缓冲区。它仅适用于没有嵌入的NUL字节的编码数据。此格式需要两个参数。第一个仅用作输入,并且必须是指向编码的名称作为NUL终止字符串的
const char * ,或NULL,在这种情况下使用
如果Python不知道指定的编码,则会引发异常。第二个参数必须是'utf-8'
编码。char**
;它引用的指针的值将被设置为带有参数文本的内容的缓冲区。文本将按第一个参数指定的编码进行编码。PyArg_ParseTuple()
将分配所需大小的缓冲区,将编码数据复制到此缓冲区并调整*缓冲区以引用新分配的存储。调用者负责调用PyMem_Free()
以在使用后释放分配的缓冲区。et
(str
,bytes
或bytearray
)[const char * encoding,char ** buffer]- 与
es
相同,除了字节字符串对象通过而不重新编码。相反,实现假定字节字符串对象使用以as参数传递的编码。 es#
(str
)[const char * encoding,char ** buffer,int * buffer_length]在
s#
上的此变体用于将Unicode编码为字符缓冲区。与es
格式不同,此变体允许包含NUL个字符的输入数据。它需要三个参数。第一个仅用作输入,并且必须是指向编码的名称作为NUL终止字符串的
const char * ,或NULL,在这种情况下使用
如果Python不知道指定的编码,则会引发异常。第二个参数必须是'utf-8'
编码。char**
;它引用的指针的值将被设置为带有参数文本的内容的缓冲区。文本将按第一个参数指定的编码进行编码。第三个参数必须是指向整数的指针;则引用的整数将设置为输出缓冲区中的字节数。有两种操作模式:
如果* buffer指向NULL指针,则函数将分配所需大小的缓冲区,将编码数据复制到此缓冲区并设置* buffer t2 >引用新分配的存储。调用者负责调用
PyMem_Free()
以在使用后释放分配的缓冲区。如果* buffer指向非NULL t>指针(已分配的缓冲区),
PyArg_ParseTuple()
将使用此位置作为缓冲区,初始值* buffer_length作为缓冲区大小。然后它将编码的数据复制到缓冲区并且NUL终止它。如果缓冲区不够大,将设置TypeError
。注意:从Python 3.6开始,将设置一个ValueError
。在这两种情况下,将* buffer_length设置为没有后NUL字节的编码数据的长度。
et#
(str
,bytes
或bytearray
)[const char * encoding,char ** buffer,int * buffer_length]- 与
es#
相同,除了字节字符串对象通过而不重新编码。相反,实现假定字节字符串对象使用以as参数传递的编码。
Numbers¶
b
(int
)[unsigned char]- 将非负的Python整数转换为存储在C
无符号 char
中的unsigned tiny int。 B
(int
)[unsigned char]- 将Python整数转换为微小的int而不进行溢出检查,存储在C
无符号 char
中。 h
(int
)[short int]- 将Python整数转换为C
short int
。 H
(int
)[unsigned short int]- 将Python整数转换为C
无符号 短 int
,无溢出检查。 i
(int
)[int]- 将Python整数转换为简单的C
int
。 I
(int
)[unsigned int]- 将Python整数转换为C
无符号 int
,无溢出检查。 l
(int
)[long int]- 将Python整数转换为C
long int
。 k
(int
)[unsigned long]- 将Python整数转换为C
无符号 长
,而不进行溢出检查。 L
(int
)[PY_LONG_LONG]- 将Python整数转换为C
long long
。此格式仅适用于支持长 长
(或Windows上的_int64
)的平台。 K
(int
)[unsigned PY_LONG_LONG]- 将Python整数转换为C
无符号 长 长
,无溢出检查。此格式仅适用于支持无符号 长 长
(或/ t5> _int64
)。 n
(int
)[Py_ssize_t]- 将Python整数转换为C
Py_ssize_t
。 c
(长度为1的bytes
或bytearray
)[char]将Python字节(长度为1的
bytes
或bytearray
对象)转换为Cchar
。在版本3.3中更改:允许
bytearray
对象。C
(长度1的str
)[int]- 将长度为1的表示为
str
对象的Python字符转换为Cint
。 f
(float
)[float]- 将Python浮点数转换为C
float
。 d
(float
)[double]- 将Python浮点数转换为C
double
。 D
(complex
)[Py_complex]- 将Python复杂数字转换为C
Py_complex
结构。
Other objects¶
O
(object)[PyObject *]- 将Python对象(无任何转换)存储在C对象指针中。C程序因此接收被传递的实际对象。对象的引用计数不增加。存储的指针不是NULL。
O!
(object)[typeobject,PyObject *]- 将Python对象存储在C对象指针中。这类似于
O
,但有两个C参数:第一个是Python类型对象的地址,第二个是C变量的地址(类型PyObject*
如果Python对象没有必需的类型,则会引发TypeError
。
O&
(object)[转换器,任何东西]通过转换器函数将Python对象转换为C变量。这需要两个参数:第一个是函数,第二个是C变量(任意类型)的地址,转换为
void * t0 >。
转换器函数依次调用如下:status = converter(object, address);
where object is the Python object to be converted and address is the
void*
argument that was passed to thePyArg_Parse*()
function. 对于成功转换,返回的状态应为1
,如果转换失败,则返回0
。当转换失败时,转换器函数应引发异常,并保留地址的内容不被修改。如果转换器返回
Py_CLEANUP_SUPPORTED
,如果参数解析最终失败,它可能会被第二次调用,从而使转换器有机会释放它已经分配的任何内存。在第二次调用中,对象参数将为NULL; 地址将具有与原始呼叫中相同的值。在版本3.1中已更改:
Py_CLEANUP_SUPPORTED
。p
(bool
)[int]测试传入的值为真(布尔p重复),并将结果转换为等效的C真/假整数值。如果表达式为true,则将int设置为1,如果为false,则设置为0。这接受任何有效的Python值。有关Python如何测试真值的值的详细信息,请参见Truth Value Testing。
版本3.3中的新功能。
(items)
(tuple
)[matching-items]- 对象必须是Python序列,其长度为项中的格式单元数。C参数必须与项中的各个格式单位相对应。可以嵌套序列的格式单元。
可以传递“长”整数(其值超过平台的LONG_MAX
的整数),但没有进行适当的范围检查 - 当接收字段太小而无法接收时,最高有效位会被静默截断值(实际上,语义是继承自C中的downcasts - 你的里程可能会变化)。
一些其他字符在格式字符串中有意义。这些可能不会出现在嵌套括号内。他们是:
|
- 表示Python参数列表中的其余参数是可选的。与可选参数对应的C变量应被初始化为其默认值 - 当未指定可选参数时,
PyArg_ParseTuple()
不会触及相应的C变量的内容。 $
PyArg_ParseTupleAndKeywords()
only:表示Python参数列表中剩余的参数是仅限关键字的。目前,所有仅关键字的参数也必须是可选参数,因此必须始终在格式字符串中的$
之前指定|
。版本3.3中的新功能。
:
- 格式单元列表在这里结束;冒号之后的字符串用作错误消息中的函数名称(
PyArg_ParseTuple()
引发的异常的“关联值”)。 ;
- 格式单元列表在这里结束;分号后的字符串用作默认错误消息的错误消息而不是。
:
和;
互相排斥。
请注意,提供给调用者的任何Python对象引用都是借用的引用;不要递减他们的引用计数!
传递给这些函数的附加参数必须是类型由格式字符串确定的变量的地址;这些用于存储来自输入元组的值。有一些情况,如上述格式单元列表中所述,其中这些参数用作输入值;它们应该匹配在这种情况下为相应格式单元指定的内容。
要使转换成功,arg对象必须与格式匹配,且格式必须用尽。成功时,PyArg_Parse*()
函数返回true,否则返回false并引发适当的异常。当PyArg_Parse*()
函数由于格式单元之一的转换失败而失败时,对应于该格式单元和以下格式单元的地址处的变量保持不变。
API Functions¶
- 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[], ...)¶ 解析将位置和关键字参数都转换为局部变量的函数的参数。成功返回true;在失败时,它返回false并引发适当的异常。
- 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, ...)¶ 用于解构“旧式”函数的参数列表的函数 - 这些函数使用在Python 3中已删除的
METH_OLDARGS
参数解析方法。这不建议在新代码中的参数解析中使用,并且标准解释器中的大多数代码已被修改为不再为此目的使用此参数。然而,它仍然是分解其他元组的方便方式,并且可以继续用于该目的。
- int
PyArg_UnpackTuple
(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, ...)¶ 参数检索的一种更简单的形式,它不使用格式字符串来指定参数的类型。使用此方法检索其参数的函数应在函数表或方法表中声明为
METH_VARARGS
。包含实际参数的元组应该作为args传递;它必须实际上是一个元组。元组的长度必须至少为min且不超过max; min和max可以相等。另外的参数必须传递给函数,每个函数应该是一个指向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)
Building values¶
- PyObject*
Py_BuildValue
(const char *format, ...)¶ - 返回值:新引用。
基于类似于由
PyArg_Parse*()
函数族接受的格式字符串和值序列创建新值。在发生错误的情况下返回值或NULL;如果返回NULL,则会引发异常。Py_BuildValue()
不总是构建一个元组。只有当它的格式字符串包含两个或多个格式单元时,它才构建一个元组。如果格式字符串为空,则返回None
;如果它只包含一个格式单元,则返回由该格式单元描述的任何对象。要强制返回大小为0或1的元组,请对格式字符串进行括号。当将内存缓冲区作为参数传递以提供数据以构建对象时,对于
s
和s#
格式,将复制所需的数据。调用者提供的缓冲区从不会被由Py_BuildValue()
创建的对象引用。In other words, if your code invokesmalloc()
and passes the allocated memory toPy_BuildValue()
, your code is responsible for callingfree()
for that memory oncePy_BuildValue()
returns.在下面的描述中,引用的形式是格式单元; (圆括号)中的条目是格式化单元将返回的Python对象类型;并且[正方形]括号中的条目是要传递的C值的类型。
字符空格,制表符,冒号和逗号在格式字符串中被忽略(但不在格式单位内,例如
s#
)。这可以用于使长格式字符串更可读。s
(str
或None
)[char *]- 使用
'utf-8'
编码将以null结尾的C字符串转换为Pythonstr
对象。如果C字符串指针NULL,则使用None
。 s#
(str
或None
)[char *,int]- 使用
'utf-8'
编码将C字符串及其长度转换为Pythonstr
对象。如果C字符串指针NULL,则忽略长度,并返回None
。 y
(bytes
)[char *]- 这会将C字符串转换为Python
bytes
对象。如果C字符串指针NULL,则返回None
。 y#
(bytes
)[char *,int]- 这将一个C字符串及其长度转换为一个Python对象。如果C字符串指针NULL,则返回
None
。 z
(str
orNone
) [char *]- 与
s
相同。 z#
(str
或None
)[char *,int]- 与
s#
相同。 u
(str
)[Py_UNICODE *]- 将Unicode(UCS-2或UCS-4)数据的以null结尾的缓冲区转换为Python Unicode对象。如果Unicode缓冲区指针NULL,则返回
None
。 u#
(str
)[Py_UNICODE *,int]- 将Unicode(UCS-2或UCS-4)数据缓冲区及其长度转换为Python Unicode对象。如果Unicode缓冲区指针NULL,则忽略长度并返回
None
。 U
(str
或None
)[char *]- 与
s
相同。 U#
(str
或None
)[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
无符号 char
转换为Python整数对象。 H
(int
)[unsigned short int]- 将C
无符号 短 int
转换为Python整数对象。 I
(int
)[unsigned int]- 将C
无符号 int
转换为Python整数对象。 k
(int
)[unsigned long]- 将C
无符号 长
转换为Python整数对象。 L
(int
)[PY_LONG_LONG]- 将C
long long
转换为Python整数对象。仅适用于在Windows上支持长 长
(或_int64
)的平台。 K
(int
)[unsigned PY_LONG_LONG]- 将C
无符号 长 长
转换为Python整数对象。仅适用于支持无符号 长 长
(或无符号 _int64
)。 n
(int
)[Py_ssize_t]- 将C
Py_ssize_t
转换为Python整数。 c
(长度为1的bytes
)[char]- 将表示一个字节的C
int
转换为长度为1的Pythonbytes
对象。 C
(长度1的str
)[int]- 将表示字符的C
int
转换为长度为1的Pythonstr
对象。 d
(float
)[double]- 将C
double
转换为Python浮点数。 f
(float
)[float]- 将C
float
转换为Python浮点数。 D
(complex
)[Py_complex *]- 将C
Py_complex
结构转换为Python复数。 O
(object)[PyObject *]- 传递一个不受影响的Python对象(除了它的引用计数,它增加一)。如果传入的对象是NULL指针,则假定这是由于产生参数的调用发现错误并设置异常引起的。因此,
Py_BuildValue()
将返回NULL,但不会引发异常。如果尚未引发任何异常,则会设置SystemError
。 S
- 与
O
相同。 N
(object)[PyObject *]- 与
O
相同,除了它不增加对象上的引用计数。在通过调用参数列表中的对象构造函数创建对象时有用。 O&
(object)[转换器,任何东西]- 通过转换器函数将任何转换为Python对象。该函数以任何(应与
void *
兼容)作为其参数调用, “new”Python对象,如果发生错误,则为NULL。 (items)
(tuple
)[matching-items]- 将C值序列转换为具有相同数量项目的Python元组。
[items]
(list
)[matching-items]- 将C值序列转换为具有相同项目数的Python列表。
{items}
(dict
)[matching-items]- 将C值序列转换为Python字典。每对连续的C值将一个项目添加到字典,分别用作键和值。
如果格式字符串中存在错误,则会设置
SystemError
异常并返回NULL。
- PyObject*
Py_VaBuildValue
(const char *format, va_list vargs)¶ 与
Py_BuildValue()
相同,除了它接受va_list而不是可变数量的参数。