Kako napišem podatke JSON v datoteko?

V spremenljivki data imam shranjene podatke JSON.

Za testiranje jih želim zapisati v besedilno datoteko, tako da mi ni treba vsakič znova zajemati podatkov iz strežnika.

Trenutno poskušam to:

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

In prejmem napako:

TypeError: must be string or buffer, not dict

Kako to popraviti?

Rešitev

Pozabili ste na dejanski del JSON - data je slovar in še ni kodiran v JSON. Za največjo združljivost (Python 2 in 3) ga zapišite takole:

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

V sodobnem sistemu (tj. Python 3 in podpora UTF-8) lahko zapišete lepšo datoteko z

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

Če želite dobiti datoteko v kodiranju *utf8* v nasprotju z datoteko v kodiranju ascii** v sprejetem odgovoru za Python 2, uporabite:

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

V Pythonu 3 je koda preprostejša:

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

V sistemu Windows je argument encoding='utf-8' za open še vedno potreben.

Če se želite izogniti shranjevanju kodirane kopije podatkov v pomnilniku (rezultat dumps) in če želite v Pythonu 2 in 3 izpisati utf8-kodirane bajtstringe, uporabite:

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

Klic codecs.getwriter je nepotreben v Pythonu 3, vendar potreben za Python 2


Bralnost in velikost:

Uporaba ensure_ascii=False omogoča boljšo berljivost in manjšo velikost:

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

Berljivost še izboljšamo, če argumentom dump ali dumps dodamo zastavice indent=4, sort_keys=True (kot predlaga dinos66). Na ta način boste v datoteki json dobili lepo razvrščeno strukturo z alinejami za ceno nekoliko večje velikosti datoteke.

Komentarji (18)

Odgovoril bi z majhno spremembo zgoraj navedenih odgovorov, in sicer da napišete lepšo datoteko JSON, ki jo lahko človeške oči bolje preberejo. V ta namen podajte sort_keys kot True in indent s 4 znaki presledka in lahko začnete. Poskrbite tudi za to, da v datoteko JSON ne bodo zapisane kode ascii:

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