Hoe schrijf ik JSON gegevens naar een bestand?

Ik heb JSON data opgeslagen in de variabele data.

Ik wil deze naar een tekstbestand schrijven om te testen, zodat ik niet elke keer de gegevens van de server hoef te halen.

Op dit moment probeer ik dit:

obj = open('data.txt', 'wb')
obj.write(data)
obj.close

En ik krijg de foutmelding:

TypeError: moet string of buffer zijn, geen dict

Hoe kan ik dit oplossen?

Oplossing

Je bent het eigenlijke JSON gedeelte vergeten - data is een dictionary en nog niet JSON-gecodeerd. Schrijf het zoals dit voor maximale compatibiliteit (Python 2 en 3):

import json
with open('data.json', 'w') as f:
    json.dump(data, f)

Op een modern systeem (d.w.z. Python 3 en UTF-8 ondersteuning), kun je een mooier bestand schrijven met

import json
with open('data.json', 'w', encoding='utf-8') as f:
    json.dump(data, f, ensure_ascii=False, indent=4)
Commentaren (21)

Om utf8-gecodeerd bestand te krijgen in tegenstelling tot ascii-gecodeerd in het geaccepteerde antwoord voor Python 2 gebruik:

import io, json
with io.open('data.txt', 'w', encoding='utf-8') as f:
  f.write(json.dumps(data, ensure_ascii=False))

De code is eenvoudiger in Python 3:

import json
with open('data.txt', 'w') as f:
  json.dump(data, f, ensure_ascii=False)

Op Windows is het encoding='utf-8' argument aan open nog steeds nodig.

Om te voorkomen dat een gecodeerde kopie van de data in het geheugen wordt opgeslagen (resultaat van dumps) en om utf8-gecodeerde bytestrings uit te voeren in zowel Python 2 als 3, gebruik je:

import json, codecs
with open('data.txt', 'wb') as f:
    json.dump(data, codecs.getwriter('utf-8')(f), ensure_ascii=False)

De codecs.getwriter aanroep is overbodig in Python 3 maar vereist voor Python 2


Leesbaarheid en grootte:

Het gebruik van ensure_ascii=False geeft betere leesbaarheid en kleinere afmetingen:

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

Verbeter de leesbaarheid verder door de vlaggen indent=4, sort_keys=True (zoals voorgesteld door dinos66) toe te voegen aan de argumenten van dump of dumps. Op deze manier krijg je'een mooi ingesprongen gesorteerde structuur in het json-bestand ten koste van een iets grotere bestandsgrootte.

Commentaren (18)

Ik zou antwoorden met een kleine wijziging van de eerder genoemde antwoorden en dat is het schrijven van een mooier JSON-bestand dat menselijke ogen beter kunnen lezen. Geef hiervoor sort_keys door als True en indent met 4 spaties en je bent goed om te gaan. Zorg er ook voor dat de ascii codes niet in je JSON bestand worden geschreven:

with open('data.txt', 'w') as outfile:
     json.dump(jsonData, outfile, sort_keys = True, indent = 4,
               ensure_ascii = False)
Commentaren (5)