Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 3兼容性问题_Python_C_Python C Extension - Fatal编程技术网

Python 3兼容性问题

Python 3兼容性问题,python,c,python-c-extension,Python,C,Python C Extension,问题描述 我必须将一些代码迁移到Python 3。汇编成功地结束了。但我在运行时遇到了一个问题: static PyObject* Parser_read(PyObject * const self, PyObject * unused0, PyObject * unused1) { //Retrieve bytes from the underlying data stream. //In this case, an iterator PyObject * const

问题描述

我必须将一些代码迁移到Python 3。汇编成功地结束了。但我在运行时遇到了一个问题:

static PyObject* Parser_read(PyObject * const self, PyObject * unused0, PyObject * unused1) {
    //Retrieve bytes from the underlying data stream.
    //In this case, an iterator
    PyObject * const i = PyIter_Next(self->readIterator);

    //If the iterator returns NULL, then no more data is available.
    if(i == NULL)
    {
        Py_RETURN_NONE;
    }

    //Treat the returned object as just bytes
    PyObject * const bytes = PyObject_Bytes(i);

    Py_DECREF(i);

    if( not bytes )
    {
        //fprintf(stderr, "try to read %s\n", PyObject_Str(bytes));
        PyErr_SetString(PyExc_ValueError, "iterable must return bytes like objects");
        return NULL;

    }

    ....
}
在我的python代码中,我有如下内容:

for data in Parser(open("file.txt")):
   ...
该代码在Python2上运行良好。但在Python 3上,我得到了:

ValueError: iterable must return bytes like objects
更新

@casevh的解决方案在所有测试用例中都能很好地工作,除了一个:当我包装流时:

def wrapper(stream):
    for data in stream:
        for i in data:
            yield i

for data in Parser(wrapper(open("file.txt", "rb"))):
    ...
我得到:
ValueError:iterable必须返回类似对象的字节

一个选项是以二进制模式打开文件:

open("file.txt", "rb")
这将创建一个迭代器,返回字节序列


Python3字符串被假定为Unicode,如果没有正确的编码/解码,它们不应该被解释为字节序列。如果您正在读取纯ASCII文本,而不是二进制数据流,则还可以将Unicode转换为ASCII。请参阅
PyUnicode\u asasitring()
和相关函数。

一个选项是以二进制模式打开文件:

open("file.txt", "rb")
这将创建一个迭代器,返回字节序列


Python3字符串被假定为Unicode,如果没有正确的编码/解码,它们不应该被解释为字节序列。如果您正在读取纯ASCII文本,而不是二进制数据流,则还可以将Unicode转换为ASCII。请参阅
PyUnicode\u asasitring()
和相关函数。

一个选项是以二进制模式打开文件:

open("file.txt", "rb")
这将创建一个迭代器,返回字节序列


Python3字符串被假定为Unicode,如果没有正确的编码/解码,它们不应该被解释为字节序列。如果您正在读取纯ASCII文本,而不是二进制数据流,则还可以将Unicode转换为ASCII。请参阅
PyUnicode\u asasitring()
和相关函数。

一个选项是以二进制模式打开文件:

open("file.txt", "rb")
这将创建一个迭代器,返回字节序列


Python3字符串被假定为Unicode,如果没有正确的编码/解码,它们不应该被解释为字节序列。如果您正在读取纯ASCII文本,而不是二进制数据流,则还可以将Unicode转换为ASCII。请参见
PyUnicode\u asasitring()
和相关函数。

正如@casevh所指出的,在Python中,您需要确定数据是二进制的还是文本的。您正在迭代行的事实使我认为后者就是这样


在Python2中工作,因为迭代
str
将产生1个字符的字符串;在Python3中,对
字节
对象进行迭代将生成0-255范围内的整数字节。通过使用范围并一次切片1个字节/字符,可以使代码在Python 2和Python 3中的工作方式相同(与上述代码的Python 2行为相同):

def wrapper(stream):
    for data in stream:
        for i in range(len(data)):
            yield data[i:i + 1]


另外,您的C扩展代码中还有一个错误:
Parser\u read
接受3个参数,其中2个被命名为
unused\u x
。只有带注释的方法接受3个参数(
PyCFunctionWithKeywords
);所有其他函数,包括
METH_NOARGS
必须是具有两个参数的函数(
PyCFunction
)。

正如@casevh所指出的,在Python中,您需要确定数据是二进制的还是文本。您正在迭代行的事实使我认为后者就是这样


在Python2中工作,因为迭代
str
将产生1个字符的字符串;在Python3中,对
字节
对象进行迭代将生成0-255范围内的整数字节。通过使用范围并一次切片1个字节/字符,可以使代码在Python 2和Python 3中的工作方式相同(与上述代码的Python 2行为相同):

def wrapper(stream):
    for data in stream:
        for i in range(len(data)):
            yield data[i:i + 1]


另外,您的C扩展代码中还有一个错误:
Parser\u read
接受3个参数,其中2个被命名为
unused\u x
。只有带注释的方法接受3个参数(
PyCFunctionWithKeywords
);所有其他函数,包括
METH_NOARGS
必须是具有两个参数的函数(
PyCFunction
)。

正如@casevh所指出的,在Python中,您需要确定数据是二进制的还是文本。您正在迭代行的事实使我认为后者就是这样


在Python2中工作,因为迭代
str
将产生1个字符的字符串;在Python3中,对
字节
对象进行迭代将生成0-255范围内的整数字节。通过使用范围并一次切片1个字节/字符,可以使代码在Python 2和Python 3中的工作方式相同(与上述代码的Python 2行为相同):

def wrapper(stream):
    for data in stream:
        for i in range(len(data)):
            yield data[i:i + 1]


另外,您的C扩展代码中还有一个错误:
Parser\u read
接受3个参数,其中2个被命名为
unused\u x
。只有带注释的方法接受3个参数(
PyCFunctionWithKeywords
);所有其他函数,包括
METH_NOARGS
必须是具有两个参数的函数(
PyCFunction
)。

正如@casevh所指出的,在Python中,您需要确定数据是二进制的还是文本。您正在迭代行的事实使我认为后者就是这样


在Python2中工作,因为迭代
str
将产生1个字符的字符串;在Python3中,对
字节
对象进行迭代将生成0-255范围内的整数字节。通过使用范围并一次切片1个字节/字符,可以使代码在Python 2和Python 3中的工作方式相同(与上述代码的Python 2行为相同):

def wrapper(stream):
    for data in stream:
        for i in range(len(data)):
            yield data[i:i + 1]

另外,您的C扩展代码中还有一个错误:
Parser\u read
接受3个参数,其中2个被命名为
unused\u x
。只有带3 arg注释的方法