Suche nach einer einfachen Wrapper-Klasse für dict
Ermöglichung des Zugriffs auf bzw. der Zuweisung von Attributen (Punktnotation) Ich war mit den bestehenden Optionen aus den folgenden Gründen nicht zufrieden.
dataclasses
, pydantic
usw. sind großartig, erfordern aber eine statische Definition des Inhalts. Außerdem können sie nicht ersetzen dict
in Code, der sich auf dict
da sie nicht dieselben Methoden und __getitem__()
Syntax wird nicht unterstützt.
Daher habe ich Folgendes entwickelt MetaDict . Es verhält sich genau wie dict
sondern ermöglicht die Punktnotation und die automatische IDE-Vervollständigung (wenn das Objekt im RAM geladen ist) ohne die Unzulänglichkeiten und potenziellen Namensraumkonflikte anderer Lösungen. Alle Funktionen und Anwendungsbeispiele können auf GitHub gefunden werden (siehe Link oben).
Vollständige Offenlegung: Ich bin der Autor von MetaDict .
Unzulänglichkeiten/Einschränkungen, auf die ich beim Ausprobieren anderer Lösungen gestoßen bin:
- Süchtig
- Keine automatische Tastenvervollständigung in der IDE
- Verschachtelte Tastenbelegung kann nicht ausgeschaltet werden
- Neu zugewiesen
dict
Objekte werden nicht so konvertiert, dass sie den Schlüsselzugriff im Attributstil unterstützen
- Eingebauter Schattentyp
Dict
- Prodikt
- Keine automatische Schlüsselvervollständigung in der IDE ohne Definition eines statischen Schemas (ähnlich wie bei
dataclass
)
- Keine rekursive Umwandlung von
dict
Objekte, wenn sie eingebettet sind in list
oder andere eingebaute Iterabilien
- AttrDict
- Keine automatische Tastenvervollständigung in der IDE
- Konvertiert
list
Objekte zu tuple
hinter den Kulissen
- Munch
- Eingebaute Methoden wie
items()
, update()
usw. können überschrieben werden mit obj.items = [1, 2, 3]
- Keine rekursive Umwandlung von
dict
Objekte, wenn sie eingebettet sind in list
oder andere eingebaute Iterabilien
- EasyDict
- Nur Strings sind gültige Schlüssel, aber
dict
akzeptiert alle hashfähigen Objekte als Schlüssel
- Eingebaute Methoden wie
items()
, update()
usw. können überschrieben werden mit obj.items = [1, 2, 3]
- Eingebaute Methoden verhalten sich nicht wie erwartet:
obj.pop('unknown_key', None)
wirft ein AttributeError
Hinweis: Ich habe eine ähnliche Antwort in diesem Stackoverflow der damit zusammenhängt.
6 Stimmen
Ich habe vor kurzem versucht, etwas Ähnliches zu tun, aber ein wiederkehrender Wörterbuchschlüssel ("from" - ein Python-Schlüsselwort) hat mich daran gehindert, es zu tun. Denn sobald man versuchte, mit "x.from" auf dieses Attribut zuzugreifen, erhielt man einen Syntaxfehler.
3 Stimmen
Das ist in der Tat ein Problem, aber ich kann auf "from" verzichten, um das Leben einfacher zu machen, wenn ich auf große Diktatkonstrukte zugreife:) die Eingabe von x['a']['d'][1]['foo'] ist wirklich lästig, also gilt x.a.d[1].foo. wenn Sie from benötigen, können Sie über getattr(x, 'from') darauf zugreifen oder stattdessen _from als Attribut verwenden.
7 Stimmen
from_
statt_from
laut PEP 8 .1 Stimmen
Sie können verwenden
getattr(x, 'from')
statt der Umbenennung des Attributs.4 Stimmen
Die meisten dieser "Lösungen" scheinen nicht zu funktionieren (selbst die akzeptierte, erlaubt keine verschachtelten
d1.b.c
), ist es meiner Meinung nach klar, dass Sie etwas aus einer Bibliothek verwenden sollten, z. B. namedtuple aus Sammlungen , como diese Antwort suggeriert, ...2 Stimmen
Bunch - Verwenden Sie ein Python-Dict wie ein Objekt: thechangelog.com/bunch-lets-use-python-dict-like-object