Iteration in Klasse

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.
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Dienstag 16. Januar 2007, 18:17

Ok, Thx. Dann fülle ich mich diesbezüglich nun sicherer. War mir nie wirklich sicher ob man das so wie bei einem echten ``dict`` behandeln soll.

lg
capsule5
User
Beiträge: 28
Registriert: Sonntag 10. Dezember 2006, 18:49

Mittwoch 17. Januar 2007, 09:37

birkenfeld hat geschrieben:Wenn der OP nach Nachnamen zugreifen will, und normalerweise nur nach Nachnamen, lohnt es sich ein Dictionary zu verwenden, dessen Keys Nachnamen sind, und dann zumindest __getitem__ zu ueberladen, damit man so zugreifen kann:

Code: Alles auswählen

mitarbeiter["Mueller"]
Hallo birkenfeld,
wie muss ich __getitem__ anpassen, um etwa über "mitarbeiter["Mueller"].tel" den Eintrag verwenden zu können?
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Mittwoch 17. Januar 2007, 10:17

Beispiel:

Code: Alles auswählen

# Vereinfacht! Nimmt alle Keyword-Argumente als Daten an.
# Normalerweise würde man das überprüfen
class Einer(object):
     def __init__(self, **kw):
         self.__dict__.update(kw)

class Mehrere(object):
    def __init__(self):
        self._m = {}
    def add(self, m):
        self._m[m.name] = m
    def __getitem__(self, name):
        return self._m.get(name)
    # etc.

c = Mehrere()
c.add(Einer(name="Mueller", tel="0800"))
c.add(Einer(name="Maier", tel="0801"))

print c["Maier"].tel
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
Benutzeravatar
jens
Moderator
Beiträge: 8483
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Mittwoch 17. Januar 2007, 10:52

birkenfeld hat geschrieben:Beispiel:
Sollte die Klasse "Einer" nicht besser von dict erben, anstatt von object?

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
BlackJack

Mittwoch 17. Januar 2007, 11:14

Ich würd' gerne Anmerken, dass Nachnamen kein eindeutiger Schlüssel sind.
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Mittwoch 17. Januar 2007, 11:24

jens hat geschrieben:
birkenfeld hat geschrieben:Beispiel:
Sollte die Klasse "Einer" nicht besser von dict erben, anstatt von object?
Wieso?
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
capsule5
User
Beiträge: 28
Registriert: Sonntag 10. Dezember 2006, 18:49

Mittwoch 17. Januar 2007, 11:30

birkenfeld hat geschrieben:Beispiel:

Code: Alles auswählen

# Vereinfacht! Nimmt alle Keyword-Argumente als Daten an.
# Normalerweise würde man das überprüfen
class Einer(object):
     def __init__(self, **kw):
         self.__dict__.update(kw)

class Mehrere(object):
    def __init__(self):
        self._m = {}
    def add(self, m):
        self._m[m.name] = m
    def __getitem__(self, name):
        return self._m.get(name)
    # etc.

c = Mehrere()
c.add(Einer(name="Mueller", tel="0800"))
c.add(Einer(name="Maier", tel="0801"))

print c["Maier"].tel
Sieht schon gut aus!
fehlt noch eine Iteration

Code: Alles auswählen

for mrX in c:
    print mrX.name, mrX.tel
:?: Wie muss ich die Klasse erweitern?
Benutzeravatar
jens
Moderator
Beiträge: 8483
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Mittwoch 17. Januar 2007, 11:30

Ein print c["Maier"] sieht so aus, wenn es von object erbt: <__main__.Einer object at 0x00A70CD0>
OK, man könnte noch die __repr__ Methode neu gestalten...

Aber so geht's doch auch:

Code: Alles auswählen

class Einer(dict):
    def __init__(self, **kw):
        dict.__init__(self, kw)

class Mehrere(object):
    def __init__(self):
        self._m = {}
    def add(self, m):
        self._m[m["name"]] = m
    def __getitem__(self, name):
        return self._m.get(name)
    # etc.

c = Mehrere()
c.add(Einer(name="Mueller", tel="0800"))
c.add(Einer(name="Maier", tel="0801"))

print c["Maier"]["tel"]
print c["Maier"]["name"]
print c["Maier"]
Ausgabe:
0801
Maier
{'tel': '0801', 'name': 'Maier'}
Ich muß zugeben, das ich eigentlich lieber mit dicts hantiere, als objecte mit Attributen ;)

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Mittwoch 17. Januar 2007, 11:38

capsule5 hat geschrieben: Sieht schon gut aus!
fehlt noch eine Iteration

Code: Alles auswählen

for mrX in c:
    print mrX.name, mrX.tel
:?: Wie muss ich die Klasse erweitern?
So:

Code: Alles auswählen

class Mehrere(...):
    def __iter__(self):
        return self._m.itervalues()
Und dann solltest du dir natürlich noch überlegen, was BlackJack gesagt hat, dass es nämlich Probleme gibt, sobald zwei Angestellte den gleichen Nachnamen haben.
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
capsule5
User
Beiträge: 28
Registriert: Sonntag 10. Dezember 2006, 18:49

Mittwoch 17. Januar 2007, 12:23

birkenfeld hat geschrieben: So:

Code: Alles auswählen

class Mehrere(...):
    def __iter__(self):
        return self._m.itervalues()
Und dann solltest du dir natürlich noch überlegen, was BlackJack gesagt hat, dass es nämlich Probleme gibt, sobald zwei Angestellte den gleichen Nachnamen haben.
SUPER, DANKE!
Es ist schon klar, dass der Nachname i. A. kein eindeutiges Kriterium ist. Hier ist das jedoch kein Problem.

Nochmals Dank an alle für die Lösungsvorschläge!
Antworten