Seite 1 von 1

Dictionary in Attribute schreibweise

Verfasst: Freitag 29. August 2008, 13:30
von alexander255
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

Verfasst: Freitag 29. August 2008, 13:36
von BlackVivi

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 :)?

Verfasst: Freitag 29. August 2008, 13:52
von würmchen
sieht auf jeden fall schick aus...

Verfasst: Freitag 29. August 2008, 14:13
von Rebecca
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...

Verfasst: Freitag 29. August 2008, 14:27
von BlackVivi

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...)

Verfasst: Freitag 29. August 2008, 14:28
von Leonidas
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 :)

Verfasst: Freitag 29. August 2008, 14:30
von Lonestar
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?

Verfasst: Freitag 29. August 2008, 14:40
von Leonidas
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).

Verfasst: Freitag 29. August 2008, 14:52
von CM
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

Verfasst: Freitag 29. August 2008, 15:01
von str1442
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.

Verfasst: Freitag 29. August 2008, 15:37
von alexander255
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

Verfasst: Freitag 29. August 2008, 16:04
von lunar
"lxml.objectify"?

Verfasst: Freitag 29. August 2008, 16:12
von alexander255
Was ist lxml.objectify ?

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

Verfasst: Freitag 29. August 2008, 16:18
von lunar
Google ist schon wirklich schwer zu benutzen ...


Tipp: Es ist gleich das erste Ergebnis ;)

Verfasst: Freitag 29. August 2008, 16:50
von alexander255
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