Hoe schrijf ik JSON-gegevens naar een bestand?

Ik heb JSON-gegevens opgeslagen in de variabele data.

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

Momenteel probeer ik dit:

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

En ik krijg deze foutmelding:

TypeError: moet string of buffer zijn, niet dict

Hoe dit op te lossen?


Antwoord 1, autoriteit 100%

Je bent het eigenlijke JSON-gedeelte vergeten – datais een woordenboek en nog niet JSON-gecodeerd. Schrijf het zoals ditvoor 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)

Antwoord 2, autoriteit 12%

Om een utf8-gecodeerdbestand te krijgen in plaats van ascii-gecodeerdin 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)

In Windows is het argument encoding='utf-8'voor opennog steeds nodig.

Om te voorkomen dat een gecodeerde kopie van de gegevens in het geheugen wordt opgeslagen (resultaat van dumps) en om utf8-encodedbytestringen in zowel Python 2 als 3 uit te voeren, gebruikt u:

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

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


Leesbaarheid en grootte:

Het gebruik van ensure_ascii=Falsegeeft een betere leesbaarheid en kleiner formaat:

>>> 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 vlaggen toe te voegen indent=4, sort_keys=True(zoals gesuggereerd door dinos66) naar argumenten van dumpof dumps. Op deze manier krijg je een mooi ingesprongen gesorteerde structuur in het json-bestand ten koste van een iets grotere bestandsgrootte.


Antwoord 3, autoriteit 7%

Ik zou met een kleine wijziging antwoorden met bovengenoemde antwoorden en dat is om een mooier JSON-bestand te schrijven dat menselijke ogen beter kunnen lezen. Geef hiervoor sort_keysdoor als Trueen indentmet 4 spatietekens en je bent klaar om te gaan. Zorg er ook voor dat de ascii-codes niet in uw JSON-bestand worden geschreven:

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

Antwoord 4, autoriteit 5%

Lees en schrijf JSON-bestanden met Python 2+3; werkt met 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)

Uitleg van de parameters van json.dump:

  • indent: gebruik 4 spaties om elk item te laten inspringen, b.v. wanneer een nieuw dictaat wordt gestart (anders staat alles op één regel),
  • sort_keys: sorteer de sleutels van woordenboeken. Dit is handig als je json-bestanden wilt vergelijken met een diff-tool / ze onder versiebeheer wilt plaatsen.
  • separators: om te voorkomen dat Python volgspaties toevoegt

Met een pakket

Bekijk mijn hulpprogrammapakket mpuvoor een supereenvoudige en gemakkelijk te onthouden:

import mpu.io
data = mpu.io.read('example.json')
mpu.io.write('example.json', data)

JSON-bestand gemaakt

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

Veelgebruikte bestandsuitgangen

.json

Alternatieven

Voor uw aanvraag kan het volgende van belang zijn:

  • Ondersteuning door andere programmeertalen
  • Lees-/schrijfprestaties
  • Compactheid (bestandsgrootte)

Zie ook: Vergelijking van gegevensserialisatie-indelingen

Als je liever op zoek bent naar een manier om configuratiebestanden te maken, lees dan misschien mijn korte artikel Configuratiebestanden in Python


Antwoord 5

Voor degenen onder u die Griekse of andere “exotische” talen zoals ik proberen te dumpen, maar ook problemen hebben (unicode-fouten) met vreemde tekens zoals het vredessymbool (\u262E) of andere die vaak in json-geformatteerde gegevens zoals die van Twitter, zou de oplossing als volgt kunnen zijn (sort_keys is uiteraard optioneel):

import codecs, json
with codecs.open('data.json', 'w', 'utf8') as f:
     f.write(json.dumps(data, sort_keys = True, ensure_ascii=False))

Antwoord 6

JSON naar een bestand schrijven

import json
data = {}
data['people'] = []
data['people'].append({
    'name': 'Scott',
    'website': 'stackabuse.com',
    'from': 'Nebraska'
})
data['people'].append({
    'name': 'Larry',
    'website': 'google.com',
    'from': 'Michigan'
})
data['people'].append({
    'name': 'Tim',
    'website': 'apple.com',
    'from': 'Alabama'
})
with open('data.txt', 'w') as outfile:
    json.dump(data, outfile)

JSON uit een bestand lezen

import json
with open('data.txt') as json_file:
    data = json.load(json_file)
    for p in data['people']:
        print('Name: ' + p['name'])
        print('Website: ' + p['website'])
        print('From: ' + p['from'])
        print('')

Antwoord 7

Ik heb niet genoeg reputatie om opmerkingen toe te voegen, dus schrijf ik hier enkele van mijn bevindingen over deze vervelende TypeError:

Kortom, ik denk dat het een bug is in de functie json.dump()alleen in Python 2– Het kan geen Python-gegevens (woordenboek / lijst) dumpen met niet-ASCII-tekens, zelfsu het bestand opent met de parameter encoding = 'utf-8'. (d.w.z. wat je ook doet). Maar json.dumps()werkt op zowel Python 2 als 3.

Om dit te illustreren, volgt phihag’s antwoord: de code in zijn antwoord breekt in Python 2 met uitzondering van TypeError: must be unicode, not str, als datanon bevat -ASCII-tekens. (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)

Het werkt echter prima in Python 3.


Antwoord 8

Schrijf een gegevens in een bestand met behulp van JSON gebruik json.dump()of json.dumps()gebruikt.
schrijf zo om gegevens in een bestand op te slaan.

import json
data = [1,2,3,4,5]
with open('no.txt', 'w') as txtfile:
    json.dump(data, txtfile)

dit voorbeeld in de lijst is opslaan in een bestand.


Antwoord 9

json.dump(data, open('data.txt', 'wb'))

Antwoord 10

De JSON schrijven met inspringing, “pretty print”:

import json
outfile = open('data.json')
json.dump(data, outfile, indent=4)

Als u foutief geformatteerde JSON moet debuggen en een nuttig foutbericht wilt, gebruik dan de bibliotheek import simplejsonin plaats van import json(functies moeten hetzelfde zijn )


Antwoord 11

Als je probeert een panda-dataframe in een bestand te schrijven met een json-indeling, raad ik dit aan

destination='filepath'
saveFile = open(destination, 'w')
saveFile.write(df.to_json())
saveFile.close()

Antwoord 12

Alle eerdere antwoorden zijn correct, hier is een heel eenvoudig voorbeeld:

#! /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()


Antwoord 13

Het geaccepteerde antwoord is prima. Ik kwam echter de foutmelding “is niet json serializable” tegen.

Zo heb ik het opgelost
met open("file-name.json", 'w')als uitvoer:

output.write(str(response))

Hoewel het geen goede oplossing is, omdat het json-bestand dat het maakt geen dubbele aanhalingstekens zal hebben, is het echter geweldig als je op zoek bent naar snel en vies.


Antwoord 14

De JSON-gegevens kunnen als volgt naar een bestand worden geschreven

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

Schrijf naar een bestand:

with open('text1.json', 'w') as f:
     json.dump(hist1, f)

Other episodes