语句解释及变量编译¶
这些函数在创建你自己的函数时帮助很大。更多说明以及实例可参考说明文档中的 Extending and Embedding the Python Interpreter 小节。
这些函数描述的前三个,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 orPy_ssize_t
]- 像
s*
,除了它不接受易变的对象。结果存储在两个C 变量中,第一个是指向C字符串的指针,第二个是它的长度。字符串可能包含嵌入的null字节。Unicode对象都被通过'utf-8'
编码转化成C字符串。 z
(str
orNone
) [const char *]- 像
s
,但是这个Python对象也有可能是None
,那么对应的C指针指向 NULL。 z*
(str
, bytes-like object orNone
) [Py_buffer]- 像
s*
,但是这个Python对象也有可能是None
,那么对应的Py_buffer
结构中的buf
指向 NULL。 z#
(str
, 只读 bytes-like object orNone
) [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
) [Py_UNICODE *]将一个Python Unicode对象转化成指向一个以空终止的Unicode字符缓冲区的指针。你必须传入一个
Py_UNICODE
指针变量的地址,存储了一个指向已经存在的Unicode缓冲区的指针。请注意一个Py_UNICODE
类型的字符宽度取决于编译选项(16位或者32位)。Python字符串必须不能包含嵌入的null代码点;如果有,引发一个ValueError
异常。在 3.5 版更改: 以前,当Python字符串中遇到了嵌入的null代码点会引发
TypeError
。从版本 3.3 开始标记为过时,将在版本 4.0 中移除。: Part of the old-style
Py_UNICODE
API; please migrate to usingPyUnicode_AsWideCharString()
.u#
(str
) [Py_UNICODE *, int]u
的变式,存储两个C变量,第一个指针指向一个Unicode数据缓存区,第二个是它的长度。它允许null代码点。从版本 3.3 开始标记为过时,将在版本 4.0 中移除。: Part of the old-style
Py_UNICODE
API; please migrate to usingPyUnicode_AsWideCharString()
.Z
(str
orNone
) [Py_UNICODE *]像
u
,但是这个Python对象也有可能是None
,那么对应的Py_UNICODE
指针指向 NULL。从版本 3.3 开始标记为过时,将在版本 4.0 中移除。: Part of the old-style
Py_UNICODE
API; please migrate to usingPyUnicode_AsWideCharString()
.Z#
(str
orNone
) [Py_UNICODE *, int]像
u#
,但是这个Python对象也有可能是None
,那么对应的Py_UNICODE
指针指向 NULL。从版本 3.3 开始标记为过时,将在版本 4.0 中移除。: Part of the old-style
Py_UNICODE
API; please migrate to usingPyUnicode_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
orbytearray
) [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()
去释放已经分配的缓冲区。If *buffer points to a non-NULL pointer (an already allocated buffer),
PyArg_ParseTuple()
will use this location as the buffer and interpret the initial value of *buffer_length as the buffer size. It will then copy the encoded data into the buffer and NUL-terminate it. If the buffer is not large enough, aValueError
will be set.在这两个例子中,*buffer_length 被设置为编码后结尾不为NUL的数据的长度。
et#
(str
,bytes
orbytearray
) [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]- 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]将一个Python字节类型,如一个长度为1的
bytes
或者bytearray
对象,转化成一个Cchar
字符类型。在 3.3 版更改: 允许
bytearray
类型的对象。C
(str
长度为1) [int]- 将一个Python字符,如一个长度为1的
str
字符串对象,转化成一个Cint
整型类型。 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]Tests the value passed in for truth (a boolean predicate) and converts the result to its equivalent C true/false integer value. Sets the int to
1
if the expression was true and0
if it was false. This accepts any valid Python value. See Truth Value Testing for more information about how Python tests values for truth.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[], ...)¶ Parse the parameters of a function that takes both positional and keyword parameters into local variables. The keywords argument is a NULL-terminated array of keyword parameter names. Empty names denote positional-only parameters. Returns true on success; on failure, it returns false and raises the appropriate exception.
在 3.6 版更改: Added support for 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 并且不超过 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)
创建变量¶
-
PyObject*
Py_BuildValue
(const char *format, ...)¶ - Return value: New reference.
基于格式化字符串创建一个新的值和那些
PyArg_Parse*()
函数族接受的函数及一系列值类似。返回这个值或者一旦出错返回 NULL;如果返回的是 NULL 会引发一个异常。Py_BuildValue()
并不一直创建一个元组。只有当它的格式化字符串包含两个或更多的格式单元才会创建一个元组。如果格式化字符串是空,它返回None
;如果它包含一个格式单元,它返回由格式单元描述的的任一对象。用圆括号包裹格式化字符串可以强制它返回一个大小为0或者1的元组当内存缓存区的数据以参数形式传递用来构建对象时,如
s
和s#
格式单元,会拷贝需要的数据。调用者提供的缓冲区从来都不会被由Py_BuildValue()
创建的对象来引用。换句话说,如果你的代码调用malloc()
并且将分配的内存空间传递给Py_BuildValue()
,你的代码就有责任在Py_BuildValue()
返回时调用free()
。在下面的描述中,双引号的表达式使格式单元;圆括号()内的是格式单元将要返回的Python对象类型;方括号[]内的是传递的C变量(变量集)的类型
字符例如空格,制表符,冒号和逗号在格式化字符串中会被忽略(但是不包括格式单元,如
s#
)。这可以使很长的格式化字符串具有更好的可读性。s#
(str
或者None
) [char *, int]- 使用
'utf-8'
编码将一个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
或者None
) [char *]- 和``s``一样。
z#
(str
或者None
) [char *, int]- 和``s#``一样。
u
(str
) [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
) [wchar_t *, int]- Convert a Unicode (UTF-16 or UCS-4) data buffer and its length to a Python
Unicode object. If the Unicode buffer pointer is NULL, the length is ignored
and
None
is returned. 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
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]- 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]- 将一个C
int
整型代表的字符转化为Pythonbytes
长度为1的字节对象。 C
(str
长度为1) [int]- 将一个C
int
整型代表的字符转化为Pythonstr
长度为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)¶ 和
Py_BuildValue()
相同,然而它接受一个va_list类型的参数而不是可变数量的参数集。