UTF8 kodierte json Datei nur über Umweg machbar?

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

Hallo,

um ein json Objekt UTF8 kodiert zu speichern, gehe ich so vor...

Code: Alles auswählen

>>> ae = u'ä'
>>> js = json.dumps(ae, ensure_ascii=False)
>>> f.write(js.encode('utf8'))
... um es zu lesen so:

Code: Alles auswählen

>>> js = f.read()
>>> ae = json.loads(js)
Bisher habe ich damit keine Probleme, bin mir aber unsicher, ob der Umweg über `write` und `read` in Ordnung ist. Letztlich möchte ich meine Daten als UTF8 Datei, die dann als solche auch "von außen" editierbar ist, vorliegen haben.

Ich bin da jetzt nicht auf json festgelegt. Welches Format würdet ihr wählen, um Kalenderdaten in einer halbwegs durchschaubaren Struktur als Text zu speichern?

mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
BlackJack

@mutetella: Warum gehst Du diesen Umweg?
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Code: Alles auswählen

 with open("json_test.js", "w", encoding="utf-8") as f:
     json.dump(u"ä", f, ensure_ascii=False)
schreibt bei mir (Python 3.3.3) ein sauber UTF-8 codiertes Zeichen in die Datei ;-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

@Hyperion:
Leider ist die Angabe einer Dateikodierung bei `open()` erst ab Python 3 möglich.

@BlackJack:
Weil ich sonst alle unicode Kalenderdaten vor einem `json.dump` nach UTF8 kodieren muss.

mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
lunar

@mutetella "from codecs import open" in Python 2 :)
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

@lunar: Ok, damit klappts, danke!

mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
BlackJack

@mutetella: Das ist doch aber überhaupt nicht nötig! Einfach Datei öffnen mit normalem `open()` (und Binärmodus) und dann mit `json.dump()` da rein speichern. Halt auch mit dem Argument das er kein ASCII schreiben soll. `codecs.open()` braucht man dafür nicht. Ich habe immer noch nicht verstanden welches *Problem* Du eigentlich lösen willst‽

Code: Alles auswählen

with open('test.json', 'wb') as json_file:
    json.dump(u'ä', json_file, ensure_ascii=False)
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

BlackJack hat geschrieben: Ich habe immer noch nicht verstanden welches *Problem* Du eigentlich lösen willst‽
Keine Ahnung, welches Problem ich hab:

Code: Alles auswählen

Python 2.7.5+ (default, Sep 17 2013, 15:31:50) 
[GCC 4.8.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import json
>>> f = open('bla', 'wb')
>>> json.dump(u'ä', f, ensure_ascii=False)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/json/__init__.py", line 190, in dump
    fp.write(chunk)
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe4' in position 1: ordinal not in range(128)

Code: Alles auswählen

Python 3.3.3 (default, Nov 27 2013, 17:12:35) 
[GCC 4.8.2] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import json
>>> f = open('bla', 'wb')
>>> json.dump(u'ä', f, ensure_ascii=False)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.3/json/__init__.py", line 184, in dump
    fp.write(chunk)
TypeError: 'str' does not support the buffer interface
mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
BlackJack

@mutetella: Okay, das war mir neu. Warum zur Hölle hat `json.dump()` dann ein `encoding`-Argument mit dem Default-Wert 'UTF-8'? Das ist dann ja total sinnfrei… :shock:
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

@BlackJack:
Deshalb bin ich den Umweg über `json.dumps` gegangen und hab' das Ergebnis dann kodiert und abgespeichert. Das Kodieren kann ich mir durch `codecs.open` inzwischen sparen.

mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

Ich bin genauso verwirrt wie BlackJack. Kann mir irgendwer den Sinn der Optionen von json.dump erklären?
- ensure_ascii=False liefert einen Unicode-String den ein normales Fileobjekt nicht schreiben kann.
- ensure_ascii=True liefert reinen ASCII-String.
In beiden Fällen brauche ich kein Encoding. Für was zum :evil: braucht die Funktion dann eine »encoding«-Option?
BlackJack

@Sirius3: Ich glaub ich hab's: Man kann nicht nur `unicode`- sondern auch `str`-Objekte in der Struktur haben die man damit serialisiert, und diese Bytezeichenketten werden mit der angegebenen Kodierung *de*kodiert, weil JSON letztendlich ja als Unicode definiert ist und man sonst nur ASCII in `str`-Objekten haben dürfte.
Antworten