Hallo zusammen,
ich wollte einfache dictionaries unkompliziert laden und speichern.
Dieses snippet ist dabei rausgekommen: https://gist.github.com/bwbg/037580e586eec6d43fc5
Leider fehlen nahezu alle doc-strings, welche noch nie zu meinen Stärken gehörten . Lediglich ein Anwendungsbeispiel habe ich hinzugefügt.
Viel Spaß beim Auseinandernehmen.
Grüße ... bwbg
Einfache dictionaries laden und speichern
Dein Code speichert und lädt also Dictionaries als JSON Text-Dateien. Einige der Dictionary Werte werden dabei aber noch in den Verzeichnispfad eingebaut. Das könntest Du z.B. dokumentieren, insbesondere wie die Dictionary Werte den Verzeichnispfad beeinflussen.
Wenn Du eine Klasse Document mit einer Member-Variablen base und den Methoden get, put, delete und select hättest, dann bräuchtest Du die partial-Spielerei nicht mehr. Überleg mal wie unübersichtlich showcase_document.py werden würde, wenn Du mit Dictionaries aus mehreren unterschiedlichen base-Verzeichnissen arbeiten würdest.
Außerdem würde ich Dir open(_path(base, xm[_IDENTIFIER]), 'wb') statt open(_path(base, xm[_IDENTIFIER]), 'w') empfehlen. Du bekommst sonst Probleme, wenn die Dateien sowohl unter Windows als auch unter Unix benutzt werden sollen.
Wenn Du eine Klasse Document mit einer Member-Variablen base und den Methoden get, put, delete und select hättest, dann bräuchtest Du die partial-Spielerei nicht mehr. Überleg mal wie unübersichtlich showcase_document.py werden würde, wenn Du mit Dictionaries aus mehreren unterschiedlichen base-Verzeichnissen arbeiten würdest.
Außerdem würde ich Dir open(_path(base, xm[_IDENTIFIER]), 'wb') statt open(_path(base, xm[_IDENTIFIER]), 'w') empfehlen. Du bekommst sonst Probleme, wenn die Dateien sowohl unter Windows als auch unter Unix benutzt werden sollen.
@bwbg: Bezüglich des Einwands von MagBen: Lass doch `document.partial()` einfach ein `collections.namedtuple` zurückgeben. Dann kann der Aufrufer entscheiden ob er die Funktionen an einzelne Namen binden möchte oder über ein Objekt darauf zugreifen möchte. Eventuell etwas lesbarer wird es wenn Du `document.partial()` in `new()` oder `create()` oder so umbenennst.
Klassen (Document [put, delete] und eine Storage [get, select]) waren sogar meine ersten Überlegungen. Im Grunde hätten diese jedoch lediglich ein Attribut base bereitgehalten und statt base hätte ich nun ein self.base durch die Methoden schleifen müssen; darüber hinaus eben zwei Klassen und entsprechende Objekte gehabt.
Hier empfinde ich freie Funktionen angenehmer und natürlicher. Die partial-Funktion ist hier lediglich ein Hilfsmittel. Das Basisverzeichnis kann ohne weiteres direkt angegeben werden (document.get, document.set, document.delete und document.select gehören zur API).
Darüber hinaus ist partial keine Spielerei
Meines Erachtens muss die Datei nicht binär geöffnet werden. JSON erstellt Textdateien, Standardkodierung ist hier UTF-8. In der Python-Dokumentation zu open ist sogar explizit aufgeführt, dass 'w' plattformunabhängig ist. Ich lasse mich auch gerne vom Gegenteil überzeugen.
Grüße ... bwbg
@BlackJack: Der Wink mit namedtuple ist großartig (dass ich da nicht selbst drauf gekommen bin). Der Name partial ist schon sehr speziell, das muss ich zugeben. Create oder new passen aber m. E. nicht gut, da man es sehr schnell mit den anderen Funktionen in Verbindung setzen kann. Ursprünglich hieß die Funktion functions.
Hier empfinde ich freie Funktionen angenehmer und natürlicher. Die partial-Funktion ist hier lediglich ein Hilfsmittel. Das Basisverzeichnis kann ohne weiteres direkt angegeben werden (document.get, document.set, document.delete und document.select gehören zur API).
Darüber hinaus ist partial keine Spielerei
Meines Erachtens muss die Datei nicht binär geöffnet werden. JSON erstellt Textdateien, Standardkodierung ist hier UTF-8. In der Python-Dokumentation zu open ist sogar explizit aufgeführt, dass 'w' plattformunabhängig ist. Ich lasse mich auch gerne vom Gegenteil überzeugen.
Grüße ... bwbg
@BlackJack: Der Wink mit namedtuple ist großartig (dass ich da nicht selbst drauf gekommen bin). Der Name partial ist schon sehr speziell, das muss ich zugeben. Create oder new passen aber m. E. nicht gut, da man es sehr schnell mit den anderen Funktionen in Verbindung setzen kann. Ursprünglich hieß die Funktion functions.
"Du bist der Messias! Und ich muss es wissen, denn ich bin schon einigen gefolgt!"
'wb' wäre in diesem Fall ein Problem, da das json Modul bytestrings völlig zurecht nicht akzeptiert. Man müsste also in diesem Fall nochmal separat dekodieren. Da JSON whitespace ohnehin per Definition ignoriert ist es aber auch völlig egal ob man da Windows oder Unix Zeilenenden hat.
Das wirkliche Problem hier ist dass JSON Dokumente in utf-8 kodiert sein sollten. Der Standard verschwendet allerdings auch einige Buchstaben um zu erklären wie man auch problemlos alle anderen utf-* Varianten unterstützen kann. Das würde ich jetzt nicht unbedingt vollkommen ignorieren. Davon allerdings mal abgesehen verwendest du ohnehin nicht utf-8 um die Datei zu öffnen, sondern was auch immer Python3 meint wäre sinnvoll. Das muss nicht unbedingt utf-8 sein, es ist sogar sehr häufig nicht utf-8.
Das wirkliche Problem hier ist dass JSON Dokumente in utf-8 kodiert sein sollten. Der Standard verschwendet allerdings auch einige Buchstaben um zu erklären wie man auch problemlos alle anderen utf-* Varianten unterstützen kann. Das würde ich jetzt nicht unbedingt vollkommen ignorieren. Davon allerdings mal abgesehen verwendest du ohnehin nicht utf-8 um die Datei zu öffnen, sondern was auch immer Python3 meint wäre sinnvoll. Das muss nicht unbedingt utf-8 sein, es ist sogar sehr häufig nicht utf-8.