J'ai des données JSON stockées dans la variable data
.
Je veux écrire ces données dans un fichier texte pour les tester, afin de ne pas avoir à les récupérer à chaque fois sur le serveur.
Actuellement, j'essaie ceci :
obj = open('data.txt', 'wb')
obj.write(data)
obj.close
Et je reçois l'erreur :
TypeError : must be string or buffer, not dict
.
Comment résoudre ce problème ?
Vous avez oublié la partie JSON proprement dite - data
est un dictionnaire et n'est pas encore encodé en JSON. Écrivez-le [comme ceci][1] pour une compatibilité maximale (Python 2 et 3) :
import json
with open('data.json', 'w') as f:
json.dump(data, f)
Sur un système moderne (i.e. Python 3 et support UTF-8), vous pouvez écrire un fichier plus joli avec
import json
with open('data.json', 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=4)
Pour obtenir un fichier utf8-encodé par opposition à ascii-encodé dans la réponse acceptée pour Python 2, utilisez :
import io, json
with io.open('data.txt', 'w', encoding='utf-8') as f:
f.write(json.dumps(data, ensure_ascii=False))
Le code est plus simple en Python 3 :
import json
with open('data.txt', 'w') as f:
json.dump(data, f, ensure_ascii=False)
Sous Windows, l'argument encoding='utf-8'
à open
est toujours nécessaire.
Pour éviter de stocker une copie codée des données en mémoire (résultat des dumps
) et pour sortir des bytestrings utf8-encodés dans Python 2 et 3, utilisez :
import json, codecs
with open('data.txt', 'wb') as f:
json.dump(data, codecs.getwriter('utf-8')(f), ensure_ascii=False)
L'appel codecs.getwriter
est redondant en Python 3 mais nécessaire en Python 2.
La lisibilité et la taille:
L'utilisation de ensure_ascii=False
donne une meilleure lisibilité et une taille plus petite :
>>> json.dumps({'price': '€10'})
'{"price": "\\u20ac10"}'
>>> json.dumps({'price': '€10'}, ensure_ascii=False)
'{"price": "€10"}'
>>> len(json.dumps({'абвгд': 1}))
37
>>> len(json.dumps({'абвгд': 1}, ensure_ascii=False).encode('utf8'))
17
Améliorez encore la lisibilité en ajoutant les drapeaux indent=4, sort_keys=True
(comme suggéré par dinos66) aux arguments de dump
ou dumps
. De cette façon, vous obtiendrez une structure triée bien indentée dans le fichier json, au prix d'une taille de fichier légèrement plus importante.
Je répondrais en modifiant légèrement les réponses précédentes, c'est à dire en écrivant un fichier JSON plus joli que les yeux humains peuvent mieux lire. Pour cela, passez sort_keys
comme True
et indent
avec 4 caractères d'espace et vous êtes prêt à partir. Veillez également à ce que les codes ascii ne soient pas écrits dans votre fichier JSON :
with open('data.txt', 'w') as outfile:
json.dump(jsonData, outfile, sort_keys = True, indent = 4,
ensure_ascii = False)