variable - python write to file




Wie schreibe ich JSON-Daten in eine Datei? (7)

Ich habe JSON-Daten in den variablen data gespeichert.

Ich möchte dies zum Testen in eine Textdatei schreiben, damit ich nicht jedes Mal die Daten vom Server abrufen muss.

Momentan versuche ich das:

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

Und erhalte den Fehler:

TypeError: must be string or buffer, not dict

Wie behebe ich das?


Lese und schreibe JSON-Dateien mit Python 2 + 3; arbeitet mit 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)

Erklärung der Parameter von json.dump :

  • indent : Verwenden Sie 4 Leerzeichen, um jeden Eintrag einzufügen, z. B. wenn ein neues Diktat gestartet wird (andernfalls sind alle in einer Zeile),
  • sort_keys : Sortiere die Schlüssel der Wörterbücher. Dies ist nützlich, wenn Sie JSON-Dateien mit einem Diff-Tool vergleichen / unter Versionskontrolle stellen möchten.
  • separators : Um zu verhindern, dass Python nachgestellte Leerzeichen hinzufügt

Erstellte JSON-Datei

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

Gemeinsame Dateiendungen

.json

Alternativen

  • CSV: Super einfaches Format ( lesen & schreiben )
  • JSON: Schön für das Schreiben von menschenlesbaren Daten; SEHR häufig verwendet ( lesen & schreiben )
  • YAML: YAML ist eine Obermenge von JSON, aber einfacher zu lesen ( lesen und schreiben , Vergleich von JSON und YAML )
  • pickle: Ein Python-Serialisierungsformat ( Lesen & Schreiben )
  • MessagePack ( Python-Paket ): kompaktere Darstellung ( Lesen & Schreiben )
  • HDF5 ( Python-Paket ): Schön für Matrizen ( lesen und schreiben )
  • XML: existiert auch * seufz * ( read & write )

Für Ihre Anwendung könnte Folgendes wichtig sein:

  • Unterstützung durch andere Programmiersprachen
  • Lese- / Schreibleistung
  • Kompaktheit (Dateigröße)

Siehe auch: Vergleich von Datenserialisierungsformaten

Falls Sie eher nach einer Möglichkeit suchen, Konfigurationsdateien zu erstellen, sollten Sie meinen kurzen Artikel Konfigurationsdateien in Python lesen


Für diejenigen von euch, die versuchen, griechische oder andere "exotische" Sprachen wie mich auszugeben, haben aber auch Probleme (Unicode-Fehler) mit komischen Zeichen wie dem Friedenssymbol (\ u262E) oder anderen, die oft in json-formatierten Daten enthalten sind wie Twitter, könnte die Lösung wie folgt sein (sort_keys ist offensichtlich optional):

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

Ich habe nicht genug Reputation, um Kommentare hinzuzufügen, also schreibe ich hier nur ein paar meiner Erkenntnisse über diesen lästigen TypeError:

Grundsätzlich, ich denke, es ist ein Fehler in der json.dump() Funktion nur in Python 2 - Es kann nicht ein Python (Wörterbuch / Liste) json.dump() mit Nicht-ASCII-Zeichen zu json.dump() , auch wenn Sie die Datei mit dem encoding = 'utf-8' öffnen encoding = 'utf-8' Parameter. (dh egal was du tust). Aber json.dumps() funktioniert sowohl in Python 2 als auch in 3.

Um dies zu illustrieren, folgt man der Antwort von phihag: Der Code in seiner Antwort bricht in Python 2 mit der Ausnahme TypeError: must be unicode, not str , wenn data Nicht-ASCII-Zeichen enthalten. (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)

Es funktioniert jedoch in Python 3 gut.


Ich würde mit leichten Änderungen mit den oben erwähnten Antworten antworten und das ist eine verschönerte JSON-Datei zu schreiben, die menschliche Augen besser lesen können. sort_keys Sie dazu sort_keys als True und einen indent mit 4 Leerzeichen und Sie können sort_keys . Achten Sie auch darauf, dass die ASCII-Codes nicht in Ihre JSON-Datei geschrieben werden:

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

Sie haben den eigentlichen JSON-Teil vergessen - data sind ein Wörterbuch und noch nicht JSON-codiert. Schreib es so:

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

Hinweis: Funktioniert sowohl mit 3.x als auch mit 2.x.


Um eine utf8- kodierte Datei im Gegensatz zu ASCII zu erhalten, die in der akzeptierten Antwort für Python 2 kodiert ist, benutze:

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

Der Code ist in Python 3 einfacher:

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

Unter Windows ist das Argument encoding='utf-8' weiterhin erforderlich.

Um zu vermeiden, dass eine kodierte Kopie der Daten im Speicher gespeichert wird (Ergebnis von dumps ) und um utf8-codierte Bytestrings in Python 2 und 3 auszugeben, verwenden Sie:

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

Der Aufruf codecs.getwriter ist in Python 3 überflüssig, aber für Python 2 erforderlich

Lesbarkeit und Größe:

Die Verwendung von ensure_acsii=False ergibt bessere Lesbarkeit und kleinere Größe:

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

Weitere Verbesserung der Lesbarkeit durch Hinzufügen von Flags indent=4, sort_keys=True (wie von dinos66 ) zu Argumenten von dump oder dumps . Auf diese Weise erhalten Sie eine gut eingerückte sortierte Struktur in der JSON-Datei auf Kosten einer etwas größeren Dateigröße.


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




json