Am Ende habe ich beides ausprobiert AttrDict und die Bündel Bibliotheken und fand sie für meine Zwecke viel zu langsam. Nachdem ein Freund und ich uns damit befasst hatten, fanden wir heraus, dass die Hauptmethode zum Schreiben dieser Bibliotheken dazu führt, dass die Bibliothek aggressiv durch ein verschachteltes Objekt rekursiert und währenddessen Kopien des Wörterbuchobjekts erstellt. Vor diesem Hintergrund haben wir zwei wesentliche Änderungen vorgenommen. 1) Wir haben die Attribute "lazy-loaded" gemacht. 2) Anstatt Kopien eines Wörterbuchobjekts zu erstellen, erstellen wir Kopien eines leichtgewichtigen Proxy-Objekts. Dies ist die endgültige Implementierung. Die Leistungssteigerung durch die Verwendung dieses Codes ist unglaublich. Bei der Verwendung von AttrDict oder Bunch verbrauchten diese beiden Bibliotheken allein 1/2 bzw. 1/3 meiner Anfragezeit (was!?). Dieser Code hat diese Zeit auf fast nichts reduziert (irgendwo im Bereich von 0,5 ms). Dies hängt natürlich von Ihren Bedürfnissen ab, aber wenn Sie diese Funktionalität in Ihrem Code häufig verwenden, sollten Sie auf jeden Fall etwas Einfaches wie dieses verwenden.
class DictProxy(object):
def __init__(self, obj):
self.obj = obj
def __getitem__(self, key):
return wrap(self.obj[key])
def __getattr__(self, key):
try:
return wrap(getattr(self.obj, key))
except AttributeError:
try:
return self[key]
except KeyError:
raise AttributeError(key)
# you probably also want to proxy important list properties along like
# items(), iteritems() and __len__
class ListProxy(object):
def __init__(self, obj):
self.obj = obj
def __getitem__(self, key):
return wrap(self.obj[key])
# you probably also want to proxy important list properties along like
# __iter__ and __len__
def wrap(value):
if isinstance(value, dict):
return DictProxy(value)
if isinstance(value, (tuple, list)):
return ListProxy(value)
return value
Siehe die ursprüngliche Implementierung ici von https://stackoverflow.com/users/704327/michael-merickel .
Außerdem ist zu beachten, dass diese Implementierung ziemlich einfach ist und nicht alle Methoden implementiert, die Sie möglicherweise benötigen. Sie müssen diese nach Bedarf in die DictProxy- oder ListProxy-Objekte schreiben.
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