web-dev-qa-db-fra.com

L'objet JSON doit être str, pas 'octets'

En utilisant Python 3.5.1, j'ai créé un fichier texte contenant chaque ligne au format JSON: {"A": "windows", "b": "stairs" ...}

import json
path = 'folder/data.txt'
records=[json.loads(line) for line in open(path,'rb')]

Mais j'ai reçu l'erreur:

the JSON object must be str, not 'bytes'

Je n'ai aucun problème à imprimer la première ligne du fichier, je suis donc rassuré que le chemin du fichier est correct.

6
Greg

Ouvrez le fichier en mode texte, pas en mode binaire (en passant explicitement encoding='utf-8' pour remplacer la valeur par défaut du système, JSON étant généralement stocké sous le format UTF-8). Le module json ne prend que str entrée; la lecture d'un fichier ouvert en mode binaire renvoie des objets bytes:

# Using with statement just for good form; in this case it would work the
# same on CPython, but on other interpreters or different CPython use cases,
# it's easy to screw something up; use with statements all the time to build good habits
with open(path, encoding='utf-8') as f:
    records=[json.loads(line) for line in f]
3
ShadowRanger

Essayez: Records = [json.loads (line . decode () ) pour line in open (chemin, 'rb')]

2
Sandipan Karmakar

Vous ne voulez pas spécifier "rb", car la représentation binaire du fichier ne sera pas lisible par le module JSON. Vous voulez probablement l'encodage "utf-8" et "read". EDIT: Au départ, j’avais dit que ces deux valeurs étaient des valeurs par défaut, mais il a été porté à mon attention que de nombreux systèmes d’exploitation ont un codage par défaut différent et que Python utilise le paramètre système par défaut dans open (). Je recommanderais donc explicitement de spécifier le paramètre de codage "utf-8".

json prend en charge le chargement depuis un fichier ouvert avec "json.load" au lieu de "json.loads", qui se charge depuis une chaîne, de sorte que nous puissions ignorer le texte lu en tant que texte et passer directement au format JSON. Je ne pense pas que vous souhaiterez "charger" des lignes individuelles, car ce ne sera probablement pas un code JSON valide. 

import json
# open has __enter__ and __exit__ functions, so we can call it as a guard
# using "with" syntax and it'll close when the scope ends
with open(r".\myjson.json", encoding="utf-8") as fh:
    # load() is a convenience function to help us avoid iterating lines
    # on our own. It calls loads() on the whole doc and returns an obj
    json_obj = json.load(fh)
print (json_obj)
1