"multidimensionales" get für Dictionaries

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
skirnir
User
Beiträge: 33
Registriert: Sonntag 25. Januar 2015, 10:59

Hallo,

ich habe ein Dictionary, das mehrere Dictionaries enthält und will auf dessen
Elemente direkt zugreifen können. Dazu habe ich eine Subklasse von dict
geschrieben, die wie folgt aussieht:

Code: Alles auswählen

class MultiDict(dict):
    def multiget(self, keys, default=None):
        subtree = self
        for k in keys:
            try:
                subtree = subtree.get(k)
            except AttributeError:
                # kein Attribut 'get' im Subtree
                return default
            except TypeError:
                # get ist kein callable oder erwartet
                # andere Parameter
                return default
        return subtree
Scheint auch zu funktionieren:

Code: Alles auswählen

In [4]: mydict
Out[4]: {'foo': {'bar': 'baz'}, 'qux': 'quux'}

In [5]: md = MultiDict(mydict)

In [6]: md.multiget(['foo', 'bar'])
Out[6]: 'baz'

In [7]: md.multiget(['qux'])
Out[7]: 'quux'

In [8]: print(md.multiget(['qux', 'quux']))
None
Gibt es vielleicht schon ein verbreitetes Modul, das so was besser macht
(z.B. enthaltene Dictionaries haben diese Eigenschaft auch)?

Welche Probleme seht ihr mit dieser Implementierung?
Sirius3
User
Beiträge: 17738
Registriert: Sonntag 21. Oktober 2012, 17:20

@skirnir: ich würde ja erwarten, dass die Keys, die man für seine Sub-Dictionaries entweder nicht existieren, oder auf ein Wörterbuch und nichts anderes verweisen, so dass ich weder AttributeError noch TypeError abfangen würde, sondern nur KeyError:

Code: Alles auswählen

class MultiDict(dict):
    def multiget(self, keys, default=None):
        item_or_subtree = self
        try:
            for k in keys:
                item_or_subtree = item_or_subtree[k]
            return item_or_subtree
        except KeyError:
            return default
skirnir
User
Beiträge: 33
Registriert: Sonntag 25. Januar 2015, 10:59

Jetzt, wo ich deine Lösung sehe, frage ich mich, wieso ich mich so an 'get' festgebissen habe. Danke!
Antworten