Comment écrire des données JSON stockées dans le dictionnaire ? data
dans un fichier ?
f = open('data.json', 'wb')
f.write(data)
Cela donne l'erreur :
TypeError : doit être une chaîne de caractères ou un tampon, pas un dict.
Comment écrire des données JSON stockées dans le dictionnaire ? data
dans un fichier ?
f = open('data.json', 'wb')
f.write(data)
Cela donne l'erreur :
TypeError : doit être une chaîne de caractères ou un tampon, pas un dict.
data
est un dictionnaire Python. Il doit être encodé en JSON avant d'être écrit.
Utilisez 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 (c'est-à-dire Python 3 et le support UTF-8), vous pouvez écrire un fichier plus joli en utilisant :
import json
with open('data.json', 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=4)
Ver json
documentation.
@TerminalDilettante json.dump
écrit dans un fichier ou un objet de type fichier, alors que json.dumps
renvoie une chaîne de caractères.
Pour obtenir utf8 -encodé par opposition à ascii -encodé dans la réponse acceptée pour l'utilisation de Python 2 :
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, le encoding='utf-8'
argument pour open
est toujours nécessaire.
Afin d'éviter de stocker une copie codée des données en mémoire (résultat de l'opération dumps
) et de produire utf8-encodé bytestrings 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)
El codecs.getwriter
est redondant dans Python 3 mais nécessaire pour Python 2.
Lisibilité et taille :
L'utilisation de ensure_ascii=False
offre 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éliorer encore la lisibilité en ajoutant des drapeaux indent=4, sort_keys=True
(comme suggéré par dinos66 ) aux arguments de dump
o dumps
. De cette façon, vous obtiendrez une structure triée et joliment indentée dans le fichier json, au prix d'une taille de fichier légèrement supérieure.
El unicode
est superflu - le résultat de json.dumps
est déjà un objet unicode. Notez que cela échoue dans la version 3.x, où toute cette pagaille de mode de fichier de sortie a été nettoyée, et où json utilise toujours des chaînes de caractères (et des E/S de caractères) et jamais des octets.
En 2.x type(json.dumps('a'))
est <type 'str'>
. Même type(json.dumps('a', encoding='utf8'))
est <type 'str'>
.
Oui, dans la version 3.x, json utilise des chaînes de caractères, mais l'encodage par défaut est ascii. Vous devez lui dire explicitement que vous voulez que utf8
même en 3.x. Mise à jour de la réponse.
Je répondrais en modifiant légèrement les réponses précédentes, c'est-à-dire en écrivant un fichier JSON simplifié que les yeux humains peuvent mieux lire. Pour cela, passez sort_keys
como True
y indent
avec 4 caractères d'espacement 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)
@SirBenBenji Assurez-vous que la chaîne de caractères que vous essayez d'écrire suit : str.decode('utf-8').
@SirBenBenji Vous pouvez aussi essayer d'utiliser des codecs, comme le précise dinos66 ci-dessous
# -*- 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 indenter chaque entrée, par exemple lorsqu'un nouveau dict est démarré (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 mettre sous contrôle de version.separators
: Pour empêcher Python d'ajouter des blancs de fin de ligneJetez un coup d'œil à mon paquet d'utilitaires mpu
pour une 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 êtes plutôt à la recherche d'un moyen de créer des fichiers de configuration, vous pouvez lire mon court article. Fichiers de configuration en Python
Notez que force_ascii
Le drapeau est True
par défaut. Vous aurez des 6 octets illisibles. "\u20ac"
séquences pour chaque €
dans votre fichier json (ainsi que de tout autre caractère non ascii).
Pour ceux d'entre vous qui, comme moi, essaient de décharger du grec ou d'autres langues "exotiques", mais qui rencontrent des problèmes (erreurs d'unicode) avec des caractères bizarres comme le symbole de la paix ( \u262E ) ou d'autres qui sont souvent contenues dans des données au format json comme celles de Twitter, la solution pourrait être la suivante (sort_keys est évidemment facultatif) :
import codecs, json
with codecs.open('data.json', 'w', 'utf8') as f:
f.write(json.dumps(data, sort_keys = True, ensure_ascii=False))
+1 Alors que la documentation recommande l'intégration de python3 open
et l'assotié io.open
sur codecs.open
Dans ce cas, il s'agit également d'une belle amélioration de la compatibilité avec le passé. Dans python2 codecs.open
est plus "omnivore" que io.open (il peut "manger" à la fois str et unicode, en convertissant si nécessaire). On peut dire que cette codecs.open
La bizarrerie compense json.dumps
la bizarrerie de générer différents types d'objets ( str
/ unicode
) en fonction de la présence des chaînes unicode dans l'entrée.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
0 votes
Pour les drapeaux lors de l'ouverture du fichier : Ici, nous avons utilisé la lettre "w" dans notre argument, qui indique l'écriture et créera un fichier s'il n'existe pas dans la bibliothèque Le signe plus indique à la fois la lecture et l'écriture, guru99.com/lire-et-ecrire-des-fichiers-en-python.html#1