这个问题是我的 previous question 的后续问题,我试图为 Python3 编译 python-yenc。在被告知没有快速修复方法后,我决定接受挑战并完全重写它。
我唯一想不通的是如何将 PyArg_ParseTupleAndKeywords
与 io-objects 一起使用。相关代码如下:
PyObject *in_file, *out_file;
static char *kwlist[] = { "infile", "outfile", NULL };
if(!PyArg_ParseTupleAndKeywords(args, kwds, "O!O!|l", kwlist,\
&PyBytes_Type, &in_file,\
&PyBytes_Type, &out_file,\
&bytes)) return NULL;
这显然产生了
Traceback (most recent call last):
File "test.py", line 21, in <module>
print(_yenc.decode_file(b), outfile=o)
TypeError: argument 1 must be bytes, not _io.BufferedReader
如何将 _io.BufferedReader
对象传递给我的函数?
谢谢, 马丁
最佳答案
Mzialla,你不应该使用“O!”在 PyArg_ParseTupleAndKeywords 中。这样做意味着您不能传递指定类型以外的任何对象。我相信在 Python 3.2 扩展中与文件交互的典型方法不是假定任何特定类型,而是针对“协议(protocol)”进行编程。
所以你应该这样做:
if(!PyArg_ParseTupleAndKeywords(args, kwds, "OO|l", kwlist,\
&in_file, &out_file, &bytes))
...
之后,您有两个选择:使用其 Python 方法与流对象交互,或者获取流的文件描述符 (PyObject_AsFileDescriptor) 并使用操作系统级 read 对其进行操作/write功能(或同等功能)。
对于 Python 方法,您应该获取“read”方法,并调用它而不是 fread。以下内容(未经测试):
PyObject *read = PyObject_GetAttrString(in_file, "read");
if (!read) handle_error;
while(encoded < bytes || bytes == 0) {
PyObject *bytes_obj= PyObject_CallFunction(read, "i", 1);
if (!bytes || !PyBytes_Check(bytes_obj)) handle_error;
char *s = PyBytes_AS_STRING(bytes_obj);
...
}
然后您需要为写入端做类似的事情。
关于c - 将 io._BufferedReader 传递给 c 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8450386/