Seite 1 von 1

Iteration

Verfasst: Dienstag 16. November 2010, 12:28
von Xynon1
Gibt es eigentlich eine Möglichkeit über ein Klassenobjekt iterieren.
zB. wenn man es als enum nutzt.

Code: Alles auswählen

class AnimalSound:
    cat = "miau"
    dog = "wuff"
Ist nur ein Beispiel :mrgreen:,
mir geht es wirklich nur darum ob es hier ein direkte Möglichkeit gibt über AnimalSound zu iterieren. Das man zB alle Attribute und/oder alle Attributwerte bekommt, ohne eine Instanz zu haben.

Re: Iteration

Verfasst: Dienstag 16. November 2010, 12:29
von cofi
Ja, indem du `__iter__` implementierst.
Edit: Alternativ auch `__getitem__`, mehr hier: http://docs.python.org/library/functions.html#iter

Re: Iteration

Verfasst: Dienstag 16. November 2010, 12:32
von Xynon1
__iter__ nützt mir doch nur etwas bei einer Instanz, oder ?

Re: Iteration

Verfasst: Dienstag 16. November 2010, 12:51
von Xynon1
Mir schwebte eher etwas in der Richtung vor:

Code: Alles auswählen

def iterobj(obj):
    for attr in obj.__dict__:
        if not attr.startswith("_"):
            yield attr, obj.__dict__[attr]

for animal, sound in iterobj(AnimalSound):
    print(animal, sound)
Gibt es da nicht was schöneres ?

Re: Iteration

Verfasst: Dienstag 16. November 2010, 13:11
von BlackJack
@Xynon1: Du solltest auf jeden Fall von dem direkten Zugriff auf `__dir__` Abstand nehmen, denn das kann ein Objekt ja mittlerweile als Methode implementieren um auch die Namen von berechneten Attributen nach aussen bekannt zu machen. Mit einem Generatorausdruck wird's ein Einzeiler:

Code: Alles auswählen

def iter_attributes(obj):
    return ((n, getattr(obj, n)) for n in dir(obj) if not n.startswith('_'))

Re: Iteration

Verfasst: Dienstag 16. November 2010, 13:18
von cofi
Xynon1 hat geschrieben:__iter__ nützt mir doch nur etwas bei einer Instanz, oder ?
Achso ja .. dann helfen dir Metaklassen.

Re: Iteration

Verfasst: Dienstag 16. November 2010, 13:28
von Xynon1
@blackjack
Ok, danke für den Hinweis, ein paar Zeichen mehr und es ist kein Einzeiler mehr :D
und du meintest sicherlich von __dict__ wegkommen und nicht von __dir__ - da warst du wohl mit den Gedanken schon einen Schritt weiter.
cofi hat geschrieben: Achso ja .. dann helfen dir Metaklassen.
Inwiefern ?

Re: Iteration

Verfasst: Dienstag 16. November 2010, 13:45
von BlackJack
@Xynon1: Ja genau, ich meinte `__dict__`. :-)

Ich denke cofi meint wenn Du eine `Enum`-Klasse schreiben möchtest, dann hilft Dir dabei eine Metaklasse. Da gibt's auch schon fertige Implementierungen, falls Du das Rad nicht noch einmal neu erfinden möchtest.

Re: Iteration

Verfasst: Dienstag 16. November 2010, 14:33
von Xynon1
Achso, das mir aber nicht explizit um Enums geht habe ich ja schon im ersten Post geschrieben und ja ich weiß das es dafür fertige Implementierungen gibt :wink:

Im Prinzip reicht mir mein-verbesserter/dein Code.
Hierzu hätte ich nur noch eine Style frage:
Ist es wirklich besser immer Listkompression zu nutzen, da diese auch nur bis zu einem gewissen Grad besser lesbar ist, spätestens wenn sie über die Zweite Zeile geht, finde ich diese doch sehr unübersichtlich.
Bei deinem Beispiel geht es ja noch, aber bei einem weiteren "if" sollte, man dann doch lieber die Liste -dekompremieren-, oder ?

Re: Iteration

Verfasst: Dienstag 16. November 2010, 16:04
von BlackJack
Die Dinger heissen "list compre*hension*". :-) Zu viel sollte man da nicht reinstecken, aber zwei Zeilen finde ich persönlich noch in Ordnung. Drei auch noch wenn ein ``if`` beteiligt ist. Dann kann man die Operation, die einzelne Elemente beschreibt; den ``for``-Ausdruck; und die Bedingung in jeweils eigene Zeilen schreiben. Hat ein bisschen was von einer SQL-Abfrage.

In meinem Beispiel war's übrigens ein Generatorausdruck und keine "list comprehension", aber das ist syntaktisch ja sehr nah beieinander.

Letztendlich ist das "lesbar" wohl auch ein wenig Gewöhnungssache.

Re: Iteration

Verfasst: Dienstag 16. November 2010, 16:34
von Xynon1
Ok, danke für die richtig Stellung :D - oder eher :idea:
BlackJack hat geschrieben:In meinem Beispiel war's übrigens ein Generatorausdruck und keine "list comprehension", aber das ist syntaktisch ja sehr nah beieinander.
Ah richtig, die Klammern :oops: