web-dev-qa-db-ja.com

Python3エラー:initial_valueはstrまたはNoneでなければなりません

python2から3にコードを移植しているときに、URLから読み取るときにこのエラーが発生します

TypeError: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())

この行で例外がスローされます

buf = StringIO(response.read())  

Python2を使用すると、問題なく動作します。

43
AMisra

response.read()bytesのインスタンスを返しますが、 StringIO はテキスト専用のメモリ内ストリームです。代わりに BytesIO を使用してください。

から Python 3.0-Unicode Vs. 8ビットではなくテキストVs.データ)の新機能

StringIOおよびcStringIOモジュールはなくなりました。代わりに、ioモジュールをインポートし、io.StringIO または io.BytesIOはそれぞれテキストとデータ用です。

77
tynn

これは別のpython3 bytesstr問題のように見えます。応答はbytes型(python 3とstrで異なる)です。最初にresponse.read().decode('utf-8')と言ってからStringIOを使用するか、誰かが言ったようにBytesIOを使用することもできますが、strであると予想される場合は、decodeを最初にstrに入れます。

16
gabhijit

Io.StringIOの代わりにsix.StringIOの使用を検討してください。

0
Max Bileschi