J'ai des données JSON stockées dans la variable data
.
Je veux écrire ceci dans un fichier texte pour le test, donc je n'ai pas à 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 cette erreur:
TypeError: doit être une chaîne ou un tampon, pas dict
Comment régler ceci?
json.dump
écrit dans un fichier ou un objet similaire à un fichier, alors qu'iljson.dumps
renvoie une chaîne.json.dump
écrit dans un fichier texte, pas un fichier binaire. Vous obtiendrez unTypeError
si le fichier a été ouvert avecwb
. Sur les anciennes versions Python, les deuxw
nandwb
travail. Un codage explicite n'est pas nécessaire car la sortie dejson.dump
est uniquement ASCII par défaut. Si vous pouvez être sûr que votre code n'est jamais exécuté sur les versions héritées de Python et que vous et le gestionnaire du fichier JSON pouvez gérer correctement les données non ASCII, vous pouvez en spécifier une et la définirensure_ascii=False
.Pour obtenir un fichier encodé en utf8 par opposition à encodé en ascii dans la réponse acceptée pour Python 2, utilisez:
Le code est plus simple en Python 3:
Sous Windows, l'
encoding='utf-8'
argument toopen
est toujours nécessaire.Pour éviter de stocker une copie codée des données en mémoire (résultat de
dumps
) et pour générer des sous - tests codés en utf8 en Python 2 et 3, utilisez:L'
codecs.getwriter
appel est redondant en Python 3 mais requis pour Python 2Lisibilité et taille:
L'utilisation de
ensure_ascii=False
donne une meilleure lisibilité et une taille plus petite:Améliorez encore la lisibilité en ajoutant des indicateurs
indent=4, sort_keys=True
(comme suggéré par dinos66 ) aux arguments dedump
oudumps
. 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 plus grande.la source
unicode
est superflu - le résultat dejson.dumps
est déjà un objet unicode. Notez que cela échoue dans 3.x, où tout le désordre du mode de fichier de sortie a été nettoyé, et json utilise toujours des chaînes de caractères (et des E / S de caractères) et jamais d'octets.type(json.dumps('a'))
est<type 'str'>
.type(json.dumps('a', encoding='utf8'))
Est même<type 'str'>
.utf8
même en 3.x. Mis à jour la réponse.'ascii' codec can't decode byte 0xf1 in position 506755: ordinal not in range(128)
. Alors en cas de doute, utilisez la réponse 3.x!Je répondrais avec une légère modification avec les réponses susmentionnées et c'est d'écrire un fichier JSON prettifié que les yeux humains peuvent mieux lire. Pour cela, passez au
sort_keys
furTrue
et à mesureindent
avec 4 espaces et vous êtes prêt à partir. Veillez également à ce que les codes ascii ne soient pas écrits dans votre fichier JSON:la source
UnicodeEncodeError: 'ascii' codec can't encode character u'\xfc'
# -*- coding: utf-8 -*-
après le shebangUnicodeEncodeError
avec des données non ascii). Voir ma solution pour plus de détails.Lire et écrire des fichiers JSON avec Python 2 + 3; fonctionne avec unicode
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 tous seront sur une seule ligne),sort_keys
: trie les clés des dictionnaires. Ceci est utile si vous souhaitez comparer des fichiers json avec un outil diff / les placer sous contrôle de version.separators
: Pour empêcher Python d'ajouter des espaces de finAvec un forfait
Jetez un oeil à mon package utilitaire
mpu
pour un super simple et facile à retenir:Fichier JSON créé
Terminaisons de fichiers communes
.json
Alternatives
Pour votre application, les éléments suivants peuvent être importants:
Voir aussi: Comparaison des formats de sérialisation des données
Dans le cas où vous cherchez plutôt un moyen de créer des fichiers de configuration, vous voudrez peut-être lire mon court article Fichiers de configuration en Python
la source
force_ascii
indicateur estTrue
par défaut. Vous aurez des"\u20ac"
séquences illisibles de 6 octets pour chacune€
dans votre fichier json (ainsi que pour tout autre caractère non ascii).open
pour la lecture maisio.open
pour l'écriture? Est-il possible d'utiliser égalementio.open
pour la lecture? Si oui, quels paramètres doivent être transmis?Pour ceux d'entre vous qui essaient de vider le grec ou d'autres langues "exotiques" comme moi, mais qui ont également des problèmes (erreurs unicode) avec des caractères étranges tels que le symbole de paix (\ u262E) ou d'autres qui sont souvent contenus dans des données formatées json comme Twitter, la solution pourrait être la suivante (sort_keys est évidemment optionnel):
la source
open
et assotiatedio.open
pluscodecs.open
, dans ce cas , il est aussi une belle entaille rétrocompatible. En python2codecs.open
est plus "omnivore" que io.open (il peut "manger" à la fois str et unicode, en convertissant si nécessaire). On peut dire que cettecodecs.open
bizarrerie compense lajson.dumps
bizarrerie de générer différents types d'objets (str
/unicode
) en fonction de la présence des chaînes unicode en entrée.Je n'ai pas assez de réputation pour ajouter des commentaires, alors j'écris juste quelques-unes de mes conclusions sur cette TypeError ennuyeuse ici:
Fondamentalement, je pense que c'est un bug dans la
json.dump()
fonction en Python 2 uniquement - Il ne peut pas vider une donnée Python (dictionnaire / liste) contenant des caractères non ASCII, même si vous ouvrez le fichier avec leencoding = 'utf-8'
paramètre. (c'est-à-dire, peu importe ce que vous faites). Mais,json.dumps()
fonctionne à la fois sur Python 2 et 3.Pour illustrer cela, en suivant la réponse de phihag: le code dans sa réponse se casse en Python 2 à l'exception
TypeError: must be unicode, not str
, s'ildata
contient des caractères non ASCII. (Python 2.7.6, Debian):Cela fonctionne cependant très bien en Python 3.
la source
data = {'asdf': 1}
. Vous obtiendrez le notoireTypeError
avec votre (deuxième) variante.ensure_ascii
- c'est nécessaire si vous voulez obtenir une "vraie" sortie utf8. Sans cela, vous aurez un ascii simple avec 6 octets par lettre russe contre 2 octets par caractère avec ce drapeau.unicode()
partie. Je viens de réaliser pour leio
package en Python 2, leswrite()
besoinsunicode
, nonstr
.Écrivez une donnée dans un fichier en utilisant JSON utilisez json.dump () ou json.dumps () utilisé. écrire comme ceci pour stocker des données dans un fichier.
cet exemple dans la liste est stocké dans un fichier.
la source
Pour écrire le JSON avec indentation, "pretty print":
De plus, si vous devez déboguer un JSON mal formaté et que vous souhaitez un message d'erreur utile, utilisez la
import simplejson
bibliothèque au lieu deimport json
(les fonctions doivent être les mêmes)la source
la source
f = open('1.txt', 'w'); f.write('a'); input()
. Exécutez-le puis SYGTERM (Ctrl-Z
puiskill %1
sous linux,Ctrl-Break
sous Windows).1.txt
aura 0 octets. C'est parce que l'écriture a été mise en mémoire tampon et que le fichier n'a été ni vidé ni fermé au moment où SYGTERM s'est produit.with
block garantit que le fichier est toujours fermé comme le fait le bloc 'try / finally' mais plus court.Écriture de JSON dans un fichier
Lecture de JSON à partir d'un fichier
la source
si vous essayez d'écrire une trame de données pandas dans un fichier en utilisant un format json je recommanderais ceci
la source
Toutes les réponses précédentes sont correctes, voici un exemple très simple:
la source
La réponse acceptée est correcte. Cependant, j'ai rencontré une erreur "n'est pas json sérialisable" en utilisant cela.
Voici comment je l'ai corrigé avec
open("file-name.json", 'w')
comme sortie:output.write(str(response))
Bien que ce ne soit pas une bonne solution car le fichier json qu'il crée n'aura pas de guillemets doubles, cependant c'est génial si vous cherchez rapide et sale.
la source
Les données JSON peuvent être écrites dans un fichier comme suit
Écrivez dans un fichier:
la source