Ich bin kein großer Fan davon, noch mehr Holz auf ein (über) 10 Jahre altes Feuer zu legen, aber ich würde mir auch die dotwiz
Bibliothek ansehen, die ich vor Kurzem veröffentlicht habe - erst in diesem Jahr tatsächlich.
Es handelt sich um eine ziemlich kleine Bibliothek, die auch in Get (Zugriff) und Set (Erstellen) Zeiten bei Benchmarks wirklich gut abschneidet, zumindest im Vergleich zu anderen Alternativen.
Installiere dotwiz
mit pip
pip install dotwiz
Es macht alles, was du von ihm erwartest und leitet von dict
ab, sodass es wie ein normales Wörterbuch funktioniert:
from dotwiz import DotWiz
dw = DotWiz()
dw.hello = 'world'
dw.hello
dw.hello += '!'
# dw.hello und dw['hello'] liefern jetzt beide 'world!'
dw.val = 5
dw.val2 = 'Sam'
Zusätzlich kannst du es in und aus dict
Objekte umwandeln:
d = dw.to_dict()
dw = DotWiz(d) # automatische Konvertierung im Konstruktor
Das bedeutet, dass wenn etwas, auf das du zugreifen möchtest, bereits in dict
Form vorliegt, kannst du es in ein DotWiz
für einen einfachen Zugriff umwandeln:
import json
json_dict = json.loads(text)
data = DotWiz(json_dict)
print data.location.city
Und schließlich arbeite ich auch an einer bestehenden Feature-Anfrage, um automatisch neue Kind-DotWiz
Instanzen zu erstellen, damit du Dinge wie folgendes tun kannst:
dw = DotWiz()
dw['people.steve.age'] = 31
dw
# (people=(steve=(age=31)))
Vergleich mit dotmap
Ich habe einen schnellen und einfachen Leistungsvergleich mit dotmap
unten hinzugefügt.
Installiere zunächst beide Bibliotheken mit pip
:
pip install dotwiz dotmap
Das folgende Codebeispiel habe ich für Benchmark-Zwecke entwickelt:
from timeit import timeit
from dotwiz import DotWiz
from dotmap import DotMap
d = {'hey': {'so': [{'this': {'is': {'pretty': {'cool': True}}}}]}
dw = DotWiz(d)
# (hey=(so=[(this=(is=(pretty={'cool'})))]))
dm = DotMap(d)
# DotMap(hey=DotMap(so=[DotMap(this=DotMap(is=DotMap(pretty={'cool'})))]))
assert dw.hey.so[0].this['is'].pretty.cool == dm.hey.so[0].this['is'].pretty.cool
n = 100_000
print('dotwiz (erstellen): ', round(timeit('DotWiz(d)', number=n, globals=globals()), 3))
print('dotmap (erstellen): ', round(timeit('DotMap(d)', number=n, globals=globals()), 3))
print('dotwiz (zugriff): ', round(timeit("dw.hey.so[0].this['is'].pretty.cool", number=n, globals=globals()), 3))
print('dotmap (zugriff): ', round(timeit("dm.hey.so[0].this['is'].pretty.cool", number=n, globals=globals()), 3))
Ergebnisse auf meinem M1 Mac mit Python 3.10:
dotwiz (erstellen): 0.189
dotmap (erstellen): 1.085
dotwiz (zugriff): 0.014
dotmap (zugriff): 0.335
32 Stimmen
Viele der Situationen, in denen Menschen verschachtelte Dicts verwenden, könnten genauso gut oder sogar besser durch Dicts mit Tupeln als Schlüssel gelöst werden, wobei
d[a][b][c]
durchd[a, b, c]
ersetzt wird.0 Stimmen
Können Sie bitte näher erläutern, wie
d[a][b][c]
durchd[a, b, c]
ersetzt werden kann? Ich habe noch nicht verstanden, wie das gemacht werden kann.9 Stimmen
Es ist kein Zauberei: foo={}; foo[1,2,3] = "one, two, three!"; foo.keys() => [(1,2,3)]
16 Stimmen
Wow. Wow noch einmal. Ich wusste nicht, dass Tupel Schlüssel von Dict sein können. Wow zum dritten Mal.
5 Stimmen
Jedes Objekt, das "hashbar" ist, kann als Schlüssel eines Dicts verwendet werden. Die meisten unveränderlichen Objekte sind auch hashbar, aber nur, wenn alle ihre Inhalte hashbar sind. Der Code d[1, 2, 3] funktioniert, weil "," der "Erstellen eines Tupeloperators" ist; es ist dasselbe wie d[(1, 2, 3)]. Klammern sind häufig optional bei der Deklaration eines Tupels.
0 Stimmen
stackoverflow.com/questions/3031219/… hat eine Antwort, die mehr macht, als Sie wollen.
1 Stimmen
Eine Situation, in der ein Tupel nicht genauso gut ist, json.dumps, TypeError: Schlüssel müssen eine Zeichenfolge sein
0 Stimmen
pypi.python.org/pypi/easydict
0 Stimmen
Bitte sehen Sie auch stackoverflow.com/questions/4984647/…
7 Stimmen
Hast du den Fall in Betracht gezogen, in dem der Schlüssel nur einen Punkt für sich hat -
{"my.key":"value"}
? Oder wenn der Schlüssel ein Schlüsselwort ist, wie z.B. "from"? Ich habe es ein paar Mal in Betracht gezogen, und es bringt mehr Probleme und Fehlerbehebung als wahrgenutzte Vorteile.1 Stimmen
Wenn Sie nicht dazu verpflichtet sind, dict zu verwenden, können Sie stattdessen namedtuple (docs.python.org/2/library/…) verwenden - auf diese Weise können Sie auf seine Elemente über den Punkt (".") zugreifen.
0 Stimmen
Dieser Frage wird auf eine sehr ähnliche Art und Weise vernetzt: Wie man Punkt Notation für ein Wörterbuch in Python verwendet? Diese hat interessante Antworten unter Verwendung von
SimpleNamespace
aus dem integriertentypes
Modul.0 Stimmen
Siehe auch: stackoverflow.com/questions/23463684/…
1 Stimmen
@TodorMinakov einen Punkt in einem Wörterbuchschlüssel zu haben ist genauso üblich wie das Codieren auf einem Bildschirm, der auf den Kopf gestellt ist - und genauso einfach umkehrbar. Außerdem löst es keinerlei Fehler aus, wenn ein Objekt ein
from_whatever
-Attribut hat.