481 Stimmen

Wie verwende ich einen Punkt "." um auf Elemente eines Wörterbuchs zuzugreifen?

Wie mache ich Python-Wörterbuchmitglieder über einen Punkt "." zugänglich?

Zum Beispiel würde ich gerne statt mydict['val'] mydict.val schreiben.

Außerdem würde ich gerne auf verschachtelte Wörterbücher auf diese Weise zugreifen. Zum Beispiel

mydict.mydict2.val 

würde sich auf

mydict = { 'mydict2': { 'val': ... } }

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] durch d[a, b, c] ersetzt wird.

0 Stimmen

Können Sie bitte näher erläutern, wie d[a][b][c] durch d[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)]

523voto

derek73 Punkte 4456

Ich habe das immer in einer util-Datei aufbewahrt. Du kannst es auch als Mixin in deinen eigenen Klassen verwenden.

class dotdict(dict):
    """Punktnotationszugriff auf Attributwörterbucheinträge"""
    __getattr__ = dict.get
    __setattr__ = dict.__setitem__
    __delattr__ = dict.__delitem__

mydict = {'val':'es funktioniert'}
nested_dict = {'val':'verschachtelt funktioniert auch'}
mydict = dotdict(mydict)
mydict.val
# 'es funktioniert'

mydict.nested = dotdict(nested_dict)
mydict.nested.val
# 'verschachtelt funktioniert auch'

203voto

epool Punkte 6426

Sie können es mit dieser Klasse tun, die ich gerade gemacht habe. Mit dieser Klasse können Sie das Map-Objekt wie ein anderes Wörterbuch (einschließlich JSON-Serialisierung) oder mit der Punkt-Schreibweise verwenden. Ich hoffe, dass ich Ihnen helfen kann:

class Map(dict):
    """
    Beispiel:
    m = Map({'first_name': 'Eduardo'}, last_name='Pool', age=24, sports=['Soccer'])
    """
    def __init__(self, *args, **kwargs):
        super(Map, self).__init__(*args, **kwargs)
        for arg in args:
            if isinstance(arg, dict):
                for k, v in arg.items():
                    self[k] = v

        if kwargs:
            for k, v in kwargs.items():
                self[k] = v

    def __getattr__(self, attr):
        return self.get(attr)

    def __setattr__(self, key, value):
        self.__setitem__(key, value)

    def __setitem__(self, key, value):
        super(Map, self).__setitem__(key, value)
        self.__dict__.update({key: value})

    def __delattr__(self, item):
        self.__delitem__(item)

    def __delitem__(self, key):
        super(Map, self).__delitem__(key)
        del self.__dict__[key]

Beispiel für die Verwendung:

m = Map({'first_name': 'Eduardo'}, last_name='Pool', age=24, sports=['Soccer'])
# Neuen Schlüssel hinzufügen
m.new_key = 'Hallo Welt!'
# Oder
m['new_key'] = 'Hallo Welt!'
print m.new_key
print m['new_key']
# Werte aktualisieren
m.new_key = 'Yay!'
# Oder
m['new_key'] = 'Yay!'
# Schlüssel löschen
del m.new_key
# Oder
del m['new_key']

182voto

Chris Redford Punkte 15633

Install dotmap über pip

pip install dotmap

Es erledigt alles, was Sie von ihm erwarten, und leitet von dict ab, sodass es wie ein normales Wörterbuch funktioniert:

from dotmap import DotMap

m = DotMap()
m.hello = 'Welt'
m.hello
m.hello += '!'
# m.hello und m['hello'] geben jetzt beide 'Welt!' zurück
m.val = 5
m.val2 = 'Sam'

Darüber hinaus können Sie es in dict-Objekte umwandeln und umgekehrt:

d = m.toDict()
m = DotMap(d) # automatische Konvertierung im Konstruktor

Dies bedeutet, dass Sie, wenn etwas, auf das Sie zugreifen möchten, bereits in dict-Form vorliegt, es in ein DotMap für einfacheren Zugriff umwandeln können:

import json
jsonDict = json.loads(text)
data = DotMap(jsonDict)
print data.location.city

Schließlich erstellt es automatisch neue Kindinstanzen von DotMap, sodass Sie Dinge wie dies tun können:

m = DotMap()
m.people.steve.age = 31

Vergleich zu Bunch

Vollständige Offenlegung: Ich bin der Schöpfer des DotMap. Ich habe es erstellt, weil Bunch diese Funktionen nicht hatte

  • Anordnen der hinzugefügten Elemente merken und in dieser Reihenfolge iterieren
  • automatische Erstellung von Kindinstanzen von DotMap, was Zeit spart und für saubereren Code sorgt, wenn Sie eine hohe Hierarchie haben
  • Aufbau aus einem dict und rekursive Konvertierung aller Kind dict-Instanzen in DotMap

83voto

Dmitry Zotikov Punkte 1399

Verwenden Sie SimpleNamespace:

>>> from types import SimpleNamespace   
>>> d = dict(x=[1, 2], y=['a', 'b'])
>>> ns = SimpleNamespace(**d)
>>> ns.x
[1, 2]
>>> ns
namespace(x=[1, 2], y=['a', 'b'])

60voto

Kugel Punkte 18318

Leiten Sie vom Wörterbuch ab und implementieren Sie __getattr__ und __setattr__.

Oder Sie können Bunch verwenden, das sehr ähnlich ist.

Ich glaube nicht, dass es möglich ist, die integrierte dict-Klasse zu monkeypatchen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X