Python3 错误:initial_value 必须是 str 或 None,带有 StringIO

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31064981/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 09:25:46  来源:igfitidea点击:

Python3 error: initial_value must be str or None, with StringIO

pythonpython-3.xurlliburllib2stringio

提问by AMisra

While porting code from python2to 3, I get this error when reading from a URL

python2to移植代码3时,从 URL 读取时出现此错误

TypeError: initial_value must be str or None, not bytes.

类型错误:initial_value 必须是 str 或 None,而不是字节。

import urllib
import json
import gzip
from urllib.parse import urlencode
from urllib.request import Request


service_url = 'https://babelfy.io/v1/disambiguate'
text = 'BabelNet is both a multilingual encyclopedic dictionary and a semantic network'
lang = 'EN'
Key  = 'KEY'

    params = {
        'text' : text,
        'key'  : Key,
        'lang' :'EN'

        }

url = service_url + '?' + urllib.urlencode(params)
request = Request(url)
request.add_header('Accept-encoding', 'gzip')
response = urllib.request.urlopen(request)
if response.info().get('Content-Encoding') == 'gzip':
            buf = StringIO(response.read())
            f = gzip.GzipFile(fileobj=buf)
            data = json.loads(f.read())

The exception is thrown at this line

在这一行抛出异常

buf = StringIO(response.read())  

If I use python2, it works fine.

如果我使用 python2,它工作正常。

采纳答案by tynn

response.read()returns an instance of byteswhile StringIOis an in-memory stream for text only. Use BytesIOinstead.

response.read()返回byteswhile的实例StringIO是仅用于文本的内存中流。使用BytesIO来代替。

From What's new in Python 3.0 - Text Vs. Data Instead Of Unicode Vs. 8-bit

来自Python 3.0 的新增功能 - 文本 Vs。数据而不是 Unicode Vs。8 位

The StringIOand cStringIOmodules are gone. Instead, import the iomodule and use io.StringIOor io.BytesIOfor text and data respectively.

StringIOcStringIO模块都没有了。相反,导入io模块并分别使用io.StringIOio.BytesIO用于文本和数据。

回答by gabhijit

This looks like another python3 bytesvs. strproblem. Your response is of type bytes(which is different in python 3 from str). You need to get it into a string first using response.read().decode('utf-8')say and then use StringIOon it. Or you may want to use BytesIOas someone said - but if you expect it to be str, preferred way is to decodeinto an strfirst.

这看起来像是另一个 python3 bytesvs.str问题。您的回复属于类型bytes(在 python 3 中与 不同str)。您需要先使用response.read().decode('utf-8')say将其放入一个字符串中,然后再使用StringIO它。或者你可能想像BytesIO某人说的那样使用- 但如果你期望它是str,首选的方法是decode进入str第一个。

回答by Max Bileschi

Consider using six.StringIO instead of io.StringIO.

考虑使用 Six.StringIO 而不是 io.StringIO。