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 – data
is 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 open
nog 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.getwriter
is overbodig in Python 3 maar vereist voor Python 2
Leesbaarheid en grootte:
Het gebruik van ensure_ascii=False
geeft 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 dump
of 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_keys
door als True
en indent
met 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 mpu
voor 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
- CSV: supereenvoudige indeling (lezen en schrijven)
- JSON: leuk voor het schrijven van door mensen leesbare gegevens; ZEER vaak gebruikt (lezen en schrijven)
- YAML: YAML is een superset van JSON, maar gemakkelijker te lezen (lezen en schrijven, vergelijking van JSON en YAML)
- augurk: een Python-serialisatie-indeling (lezen en schrijven)
- MessagePack(Python-pakket): compactere weergave (lezen en schrijven)
- HDF5(Python-pakket): leuk voor matrices (lezen en schrijven)
- XML: bestaat ook *zucht* (lees& schrijf)
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 data
non 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 simplejson
in 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)