J'ai des données JSON stockées dans la variable data
.
Je veux écrire ceci dans un fichier texte pour le tester afin de ne pas avoir à récupérer les données du serveur à chaque fois.
Actuellement, j'essaye 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égler ceci?
Vous avez oublié la partie JSON actuelle - data
est un dictionnaire et pas encore encodé en JSON. Écrivez-le comme ceci 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 (par exemple, Python 3 et prise en charge UTF-8), vous pouvez écrire un fichier plus agréable avec
import json
with open('data.json', 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=4)
Pour obtenir tf8- encodé fichier par opposition à ascii- encodé dans la réponse acceptée pour Python 2 utilisation:
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 dans 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'
de open
est toujours nécessaire.
Pour éviter de stocker une copie codée des données en mémoire (résultat de dumps
) et de générer --- bytestrings tf8-encoded à la fois 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 dans Python 3 mais requis pour Python 2
Lisibilité et taille:
L'utilisation de ensure_ascii=False
donne une meilleure lisibilité et une taille réduite:
>>> 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 en retrait dans le fichier json au prix d’une taille de fichier légèrement supérieure.
Je répondrais avec une légère modification avec les réponses ci-dessus et il s’agirait d’écrire un fichier JSON très joli que l’œil humain peut mieux lire. Pour cela, passez sort_keys
comme True
et indent
avec 4 espaces 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)
_# -*- coding: utf-8 -*-
import json
# Make it work for Python 2+3 and with Unicode
import io
try:
to_unicode = unicode
except NameError:
to_unicode = str
# Define data
data = {'a list': [1, 42, 3.141, 1337, 'help', u'€'],
'a string': 'bla',
'another dict': {'foo': 'bar',
'key': 'value',
'the answer': 42}}
# Write JSON file
with io.open('data.json', 'w', encoding='utf8') as outfile:
str_ = json.dumps(data,
indent=4, sort_keys=True,
separators=(',', ': '), ensure_ascii=False)
outfile.write(to_unicode(str_))
# Read JSON file
with open('data.json') as data_file:
data_loaded = json.load(data_file)
print(data == data_loaded)
_
Explication des paramètres de json.dump
:
indent
: Utilisez 4 espaces pour mettre en retrait chaque entrée, par exemple. quand un nouveau dict est lancé (sinon tout sera sur une seule ligne),sort_keys
_: trier les clés des dictionnaires. Ceci est utile si vous voulez comparer des fichiers JSON avec un outil de diff/les placer sous contrôle de version.separators
: Pour empêcher Python d'ajouter des espaces finauxJetez un oeil à mon paquet d'utilitaire mpu
pour un super simple et facile à retenir:
_import mpu.io
data = mpu.io.read('example.json')
mpu.io.write('example.json', data)
_
_{
"a list":[
1,
42,
3.141,
1337,
"help",
"€"
],
"a string":"bla",
"another dict":{
"foo":"bar",
"key":"value",
"the answer":42
}
}
_
_.json
_
Pour votre application, les éléments suivants peuvent être importants:
Voir aussi: Comparaison des formats de sérialisation des données
Si vous cherchez plutôt un moyen de créer des fichiers de configuration, vous pouvez lire mon court article Fichiers de configuration en Python
Pour ceux d'entre vous qui essaient de vider le grec ou d'autres langages "exotiques" tels que moi, mais qui rencontrent également des problèmes (erreurs unicode) avec des caractères étranges tels que le symbole de la paix (\ u262E) ou d'autres qui sont souvent contenus dans des données formatées json comme celle de Twitter, la solution pourrait être la suivante (sort_keys est évidemment optionnel):
import codecs, json
with codecs.open('data.json', 'w', 'utf8') as f:
f.write(json.dumps(data, sort_keys = True, ensure_ascii=False))
Je n'ai pas assez de réputation pour ajouter des commentaires, je viens donc d'écrire certaines de mes découvertes de cet ennuyeux TypeError ici:
Fondamentalement, je pense que c'est un bogue dans la fonction json.dump()
dans Python 2 seulement - Il ne peut pas vider un Python (dictionnaire/liste ) des données contenant des caractères non-ASCII, même vous ouvrez le fichier avec le paramètre encoding = 'utf-8'
. (c'est-à-dire peu importe ce que vous faites). Mais json.dumps()
fonctionne à la fois sur Python 2 et 3.
Pour illustrer ceci, pour faire suite à la réponse de phihag: le code dans sa réponse est cassé dans Python 2 avec l'exception TypeError: must be unicode, not str
, si data
contient des caractères non-ASCII. (Python 2.7.6, Debian):
import json
data = {u'\u0430\u0431\u0432\u0433\u0434': 1} #{u'абвгд': 1}
with open('data.txt', 'w') as outfile:
json.dump(data, outfile)
Cela fonctionne cependant très bien dans Python 3.
Écrivez des données dans un fichier à l'aide de JSON, utilisez json.dump () ou json.dumps () utilisé. écrivez comme ceci pour stocker des données dans un fichier.
import json
data = [1,2,3,4,5]
with open('no.txt', 'w') as txtfile:
json.dump(data, txtfile)
cet exemple dans la liste est stocké dans un fichier.
json.dump(data, open('data.txt', 'wb'))
Pour écrire le JSON avec indentation, "joli imprimé":
import json
outfile = open('data.json')
json.dump(data, outfile, indent=4)
De même, si vous devez déboguer un JSON mal formaté et que vous souhaitez un message d'erreur utile, utilisez la bibliothèque import simplejson
au lieu de import json
(les fonctions doivent être identiques).
si vous essayez d'écrire un pandas dataframe dans un fichier utilisant un format json, je vous le recommande
destination='filepath'
saveFile = open(destination, 'w')
saveFile.write(df.to_json())
saveFile.close()
Toutes les réponses précédentes sont correctes. Voici un exemple très simple:
#! /usr/bin/env python
import json
def write_json():
# create a dictionary
student_data = {"students":[]}
#create a list
data_holder = student_data["students"]
# just a counter
counter = 0
#loop through if you have multiple items..
while counter < 3:
data_holder.append({'id':counter})
data_holder.append({'room':counter})
counter += 1
#write the file
file_path='/tmp/student_data.json'
with open(file_path, 'w') as outfile:
print("writing file to: ",file_path)
# HERE IS WHERE THE MAGIC HAPPENS
json.dump(student_data, outfile)
outfile.close()
print("done")
write_json()
Les données JSON peuvent être écrites dans un fichier comme suit
hist1 = [{'val_loss': [0.5139984398465246],
'val_acc': [0.8002029867684085],
'loss': [0.593220705309384],
'acc': [0.7687131817929321]},
{'val_loss': [0.46456472964199463],
'val_acc': [0.8173602046780344],
'loss': [0.4932038113037539],
'acc': [0.8063946213802453]}]
Ecrire dans un fichier:
with open('text1.json', 'w') as f:
json.dump(hist1, f)
La réponse acceptée est correcte. Cependant, je me suis heurté à l'erreur "is not json serializable".
Voici comment je l'ai corrigé avec open("file-name.json", 'w')
en sortie:
output.write(str(response))
Bien que ce ne soit pas une bonne solution, le fichier json qu’il crée n’aura pas de guillemets, mais c’est formidable si vous recherchez une solution rapide et sale.