Dictionary in Attribute schreibweise

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
alexander255
User
Beiträge: 30
Registriert: Montag 28. April 2008, 13:05

Hallo,

ist es möglich verschachtelte Dictionarys in Attribute-Schreibweise abzufragen?

z.B:
>>> a = {}
>>> a["b"] = {}
>>> a["b"]["c"] = "abc"
>>> print a["b"]["c"]
abc
>>> print a.b.c
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'dict' object has no attribute 'b'
sollte
>>> print a.b.c
abc
sein. :(

G Alexander
Benutzeravatar
BlackVivi
User
Beiträge: 762
Registriert: Samstag 9. Dezember 2006, 14:29
Kontaktdaten:

Code: Alles auswählen

In [10]: class MyDict(dict):
    def __getattr__(self, attr):
        return self[attr]
    def __setattr__(self, attr, value):
        self[attr] = value

In [15]: foo = MyDict()

In [16]: foo["b"] = MyDict()

In [17]: foo["b"]["c"] = "abc"

In [18]: foo.b.c
Out[18]: 'abc'

In [19]: foo.b.c = "abcd"

In [20]: foo["b"]["c"]
Out[20]: 'abcd'
Aber wozu brauchst du das :)?
würmchen
User
Beiträge: 255
Registriert: Mittwoch 7. November 2007, 14:17

sieht auf jeden fall schick aus...
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

Ich praesentiere: Das einfachste Dictionary wo gibt, vollstaendig selbst programmiert, und als extra Feature: Zugriff auf Eintraege mit Attribut-Schreibweise

Code: Alles auswählen

>>> class Bunch(): pass
...
>>> b = Bunch()
>>> b.a = 1
>>> b.hallo = "welt"
>>> b.a = "spam"
:mrgreen:

Oder noch etwas komfortabler:

Code: Alles auswählen

class Bunch:
    def __init__(self, **kwargs):
        for (key, value) in kwargs.items():
            setattr(self, key, value)

b = Bunch(a=1, hallo="welt")
Damit kann man sogar herkoemmliche Dicts umwandeln...
Offizielles Python-Tutorial (Deutsche Version)

Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
Benutzeravatar
BlackVivi
User
Beiträge: 762
Registriert: Samstag 9. Dezember 2006, 14:29
Kontaktdaten:

Code: Alles auswählen

In [5]: class Bunch(): pass
   ...: 

In [6]: b = Bunch()

In [7]: b["foo"] = 2
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)

/home/vivi/<ipython console> in <module>()

AttributeError: Bunch instance has no attribute '__setitem__'
Och manno, wieso geht das nicht ;PP Gibt schon'n Paar Unterschiede...

Code: Alles auswählen

In [10]: class MyDict(dict):
   ....:     def __getattr__(self, attr):
   ....:         return self[attr]
   ....:     def __setattr__(self, attr, value):
   ....:         self[attr] = value
   ....:         
   ....:         

In [11]: foo = MyDict()

In [12]: foo.bar = "foobar"

In [13]: foo
Out[13]: {'bar': 'foobar'}

In [18]: foo.keys()
Out[18]: ['bar']

In [19]: foo.values()
Out[19]: ['foobar']
Wobei es natürlich nicht sooooooo dolle nützlich ist, ein Dict mit attributes als Zugriffsmöglichkeiten zu haben... (spontan fällt mir eigentlich kein guter Verwendungszweck ein...)
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Rebecca hat geschrieben:Ich praesentiere: Das einfachste Dictionary wo gibt, vollstaendig selbst programmiert, und als extra Feature: Zugriff auf Eintraege mit Attribut-Schreibweise
Der Trick erinnert mich verdächtig an JavaScript :)
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Lonestar
User
Beiträge: 147
Registriert: Samstag 9. August 2008, 08:31

Hi, ich als Pythoneinsteiger (habe eigentlich c und c++ im Studium gelernt) habe eh so manchmal Verständnisprobleme warum man bestimmte Sachen in Python wie macht.
Warum erstellt ihr euch eure eigenen Klassen um ein paar Dic zu verwalten wenn es schon fertige Klassen gibt? Da ich sonst immer viel mit Arrays zu tun hatte wäre mir als Problemlösung einfach eine Liste mit Dictionarys eingefallen.

Code: Alles auswählen


>>> list =[]
>>> list.append({})
>>> list[0]["key"] = "hallo welt"
>>> list
[{'key': 'hallo welt'}]
[/list]
macht man sowas in Python nicht? Oder denke ich zu einfach?
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Lonestar hat geschrieben:Warum erstellt ihr euch eure eigenen Klassen um ein paar Dic zu verwalten wenn es schon fertige Klassen gibt?
Weil man mit ihnen oft das Problem besser abbilden kann. Ein verschachteltes List-Dict-Monster ist nur bis zu irgendeinem Grad überschaubar, wenn es weniger uberschaubar ist, kann man sich das Leben einfacher machen, indem man eine Klasse definiert, die dann auch Operationen auf den Daten ausführen kann, wodurch das ganze schön gekapselt ist.
Lonestar hat geschrieben:macht man sowas in Python nicht? Oder denke ich zu einfach?
Die Struktur ist Unsinn. Man hat ein Problem, das man lösen will, je nachdem wählt man eine passende Struktur. In deiner Struktur sehe ich nicht, welches Problem sie lösen würde ;) (ja, ich weiß dass es ein Beispiel ist, aber so eine Struktur ist kein gutes Beispiel).
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Lonestar hat geschrieben:Warum erstellt ihr euch eure eigenen Klassen um ein paar Dic zu verwalten wenn es schon fertige Klassen gibt?
Macht ja niemand im wirklichen Leben. Wenn so eine Klasse wie "MyDict" von BlackVivi erstellt wird, dann soll sie meist auch etwas mehr können als das builtin dict - sonst wäre die Ableitung eher witzlos (syntax shugar-Aspekte mal aussen vor gelassen). Hier im Forum werden solche Dinge häufig präsentiert, um die Machbarkeit zu demonstrieren.
Lonestar hat geschrieben: Da ich sonst immer viel mit Arrays zu tun hatte wäre mir als Problemlösung einfach eine Liste mit Dictionarys eingefallen.

Code: Alles auswählen


>>> list =[]
>>> list.append({})
>>> list[0]["key"] = "hallo welt"
>>> list
[{'key': 'hallo welt'}]
[/list]
macht man sowas in Python nicht? Oder denke ich zu einfach?
Das sieht eher seltsam aus:
- das builtin list wird überschrieben
- so etwas wie list.key - wie hier gewünscht - erreicht man so auch nicht
- und eine derartige Verschachtelung kommt zwar manchmal vor, aber dazu braucht es einen guten Grund. (Man kann durch entsprechende Verschachtelungen auch in Python unübersichtlichen Code schreiben ;-).)

Python und C++ tun sich da nicht viel. In beiden Fällen überlegt man sich sehr gut, ob ein dict / container reicht oder ob es eine Liste / array von dicts / containern sein muß.

Gruß,
Christian
Benutzeravatar
str1442
User
Beiträge: 520
Registriert: Samstag 31. Mai 2008, 21:13

Die Struktur ist Unsinn. Man hat ein Problem, das man lösen will, je nachdem wählt man eine passende Struktur. In deiner Struktur sehe ich nicht, welches Problem sie lösen würde Wink (ja, ich weiß dass es ein Beispiel ist, aber so eine Struktur ist kein gutes Beispiel).
Ich würde eine solche Struktur nutzen um sich nie ändernde Daten aufzubewahren, die alle zu einer Klasse dazugehören, die dann damit tolle Dinge macht, in etwa so:

Code: Alles auswählen

class Kugelschreiber:
    def __init__(self, hersteller, farbe):
         self.hersteller = hersteller #etc

data = [{"hersteller" : "A", "farbe" : "Rot"}]
objects = [Kugelschreiber(**dictx) for dictx in data]
Wobei eine Menge per set da wohl besser wäre.

Ich selbst finde das auch nicht sonderlich toll, aber eine bessere Lösung (geschweige denn irgendwelche CSV/INI Fummeleien) will mir auch nicht einfallen.
alexander255
User
Beiträge: 30
Registriert: Montag 28. April 2008, 13:05

Danke! Danke,

Der Grund für dieses Thema ist ein XML basierter language-Skript und da ist es halt schöner wenn statt

Code: Alles auswählen

msg.general["window"]["title"]["prefix"]
da

Code: Alles auswählen

msg.general.window.title.prefix
steht. :D

LG Alexander
alexander255
User
Beiträge: 30
Registriert: Montag 28. April 2008, 13:05

Was ist lxml.objectify ?

P.s.: Zum lesen verwende ich xml.dom.minidom
lunar

Google ist schon wirklich schwer zu benutzen ...


Tipp: Es ist gleich das erste Ergebnis ;)
alexander255
User
Beiträge: 30
Registriert: Montag 28. April 2008, 13:05

Sieht nett aus aber ich habe das jetzt mit xml.dom.minidom umgesetzt,
welches mich an php strings erinnert:
Die eine function ist Node... die nächste ...node und die dritte set... :? :? :?

Na ja ich durchgehalten
Antworten