Jag har JSON-data lagrat i variabeln data
.
Jag vill skriva detta till en textfil för testning så att jag inte behöver hämta data från servern varje gång.
För närvarande försöker jag med följande:
obj = open('data.txt', 'wb')
obj.write(data)
obj.close
Och får felet:
TypeError: måste vara sträng eller buffert, inte dict
.
Hur åtgärdar jag detta?
Du glömde den faktiska JSON-delen - data
är en ordbok och ännu inte JSON-kodad. Skriv det så här för maximal kompatibilitet (Python 2 och 3):
import json
with open('data.json', 'w') as f:
json.dump(data, f)
På ett modernt system (dvs. Python 3 och stöd för UTF-8) kan du skriva en snyggare fil med
import json
with open('data.json', 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=4)
För att få en utf8-kodad fil i motsats till ascii-kodad i det accepterade svaret för Python 2, använd:
import io, json
with io.open('data.txt', 'w', encoding='utf-8') as f:
f.write(json.dumps(data, ensure_ascii=False))
Koden är enklare i Python 3:
import json
with open('data.txt', 'w') as f:
json.dump(data, f, ensure_ascii=False)
På Windows är argumentet encoding='utf-8'
till open
fortfarande nödvändigt.
För att undvika att lagra en kodad kopia av data i minnet (resultat av dumps
) och för att ge ut utf8-kodade bytestringar i både Python 2 och 3, använd:
import json, codecs
with open('data.txt', 'wb') as f:
json.dump(data, codecs.getwriter('utf-8')(f), ensure_ascii=False)
Kallelsen codecs.getwriter
är överflödig i Python 3 men nödvändig för Python 2.
Läsbarhet och storlek:
Användningen av ensure_ascii=False
ger bättre läsbarhet och mindre storlek:
>>> 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
Förbättra läsbarheten ytterligare genom att lägga till flaggorna indent=4, sort_keys=True
(enligt förslag från dinos66) till argumenten för dump
eller dumps
. På så sätt får du en snyggt indragen sorterad struktur i json-filen till priset av en något större filstorlek.
Jag skulle svara med en liten ändring av de tidigare nämnda svaren och det är att skriva en finare JSON-fil som människans ögon kan läsa bättre. För detta, skicka sort_keys
som True
och indent
med 4 mellanslagstecken och du är klar. Se också till att asciikoderna inte skrivs in i din JSON-fil:
with open('data.txt', 'w') as outfile:
json.dump(jsonData, outfile, sort_keys = True, indent = 4,
ensure_ascii = False)