web-dev-qa-db-fra.com

Erreur Python3: initial_value doit être str ou None

Lors du portage du code de python2 à 3, Je reçois cette erreur lors de la lecture d'une URL

TypeError: initial_value doit être str ou None, pas d'octets.

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

L'exception est levée à cette ligne

buf = StringIO(response.read())  

Si j'utilise python2, cela fonctionne bien.

43
AMisra

response.read() renvoie une instance de bytes tandis que StringIO est un flux en mémoire pour du texte uniquement. Utilisez BytesIO à la place.

From Nouveautés Python 3.0 - Données texte vs données au lieu de caractères Unicode 8 bits

Les modules StringIO et cStringIO ont disparu. Importez plutôt le module io et utilisez io.StringIO ou io.BytesIO pour le texte et les données, respectivement.

77
tynn

Cela ressemble à un autre problème python3 bytes contre str. Votre réponse est de type bytes (ce qui diffère de python 3 de str.).) Vous devez d'abord l'introduire dans une chaîne en utilisant response.read().decode('utf-8') dites puis utilisez StringIO dessus ou utilisez BytesIO comme quelqu'un l’a dit - mais si vous vous attendez à ce que ce soit str, le moyen préféré est de: decode dans un str premier.

16
gabhijit

Envisagez d'utiliser six.StringIO au lieu de io.StringIO.

0
Max Bileschi