web-dev-qa-db-fra.com

Comment écrire des données JSON dans un fichier?

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?

951
user1530318

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)
1770
phihag

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.

248
Antony Hatchkins

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)
156
ambodi

Lire et écrire des fichiers JSON avec Python 2 + 3; fonctionne avec unicode

_# -*- 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 finaux

Avec un paquet

Jetez 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)
_

Fichier JSON créé

_{
    "a list":[
        1,
        42,
        3.141,
        1337,
        "help",
        "€"
    ],
    "a string":"bla",
    "another dict":{
        "foo":"bar",
        "key":"value",
        "the answer":42
    }
}
_

Terminaisons de fichier communes

_.json_

Des alternatives

Pour votre application, les éléments suivants peuvent être importants:

  • Prise en charge par d'autres langages de programmation
  • Lecture/écriture
  • Compacité (taille de fichier)

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

102
Martin Thoma

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))
21
dinos66

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.

10
ibic

É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.

7
Vishal Gediya
json.dump(data, open('data.txt', 'wb'))
4
Alexander

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).

3
James Wierzba

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()

enter image description here

1
grepit

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)
1

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.

1
Akshat Bajaj