首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python 3兼容性问题

Python 3兼容性问题
EN

Stack Overflow用户
提问于 2015-03-10 09:40:13
回答 2查看 76关注 0票数 0

问题的描述

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

代码语言:javascript
复制
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代码中,我有这样的内容:

代码语言:javascript
复制
for data in Parser(open("file.txt")):
   ...

该代码在Python 2上运行良好。但是在Python 3上,我得到了:

代码语言:javascript
复制
ValueError: iterable must return bytes like objects

更新

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

代码语言:javascript
复制
def wrapper(stream):
    for data in stream:
        for i in data:
            yield i

for data in Parser(wrapper(open("file.txt", "rb"))):
    ...

我得到了:ValueError: iterable必须返回像对象那样的字节

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-03-10 13:14:35

一种选择是以二进制模式打开文件:

代码语言:javascript
复制
open("file.txt", "rb")

这将创建一个返回字节序列的迭代器。

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

票数 3
EN

Stack Overflow用户

发布于 2015-03-10 15:37:39

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

代码语言:javascript
复制
def wrapper(stream):
    for data in stream:
        for i in data:
            yield i

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

代码语言:javascript
复制
def wrapper(stream):
    for data in stream:
        for i in range(len(data)):
            yield data[i:i + 1]

在C扩展代码中也有一个错误:Parser_read包含3个参数,其中2个参数名为unused_x。只有一个带有METH_KEYWORDS注释的方法需要3个参数(PyCFunctionWithKeywords);所有其他参数(包括METH_NOARGS )都必须是带有2个参数(PyCFunction)的函数。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28960306

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档