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.
capsule5
User
Beiträge: 28
Registriert: Sonntag 10. Dezember 2006, 18:49

Iteration in Klasse

Beitragvon capsule5 » Dienstag 16. Januar 2007, 14:08

Hallo,

ich möchte Daten in folgender Form verwenden:
Mitarbeiter.Meier.Tel, Mitarbeiter.Meier.Fax, usw.
Dazu habe ich Klassen definiert:

Code: Alles auswählen

class MITARBEITER(object):
    def __init__(self):

        class NAME(object):
            def __init__(self, tel=0, fax=0):
                self.Tel = tel
                self.Fax = fax
       
        Meier = NAME(1234, 1220)
        Mueller = NAME(5678, 9876)

Mitarbeiter = MITARBEITER()

Wie kann ich jetzt über Mitarbeiter iterieren? Am besten wäre etwas wie

Code: Alles auswählen

for name in Mitarbeiter:
    print name.Tel

Oder ist vielleicht der ganze Ansatz falsch?
EyDu
User
Beiträge: 4866
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Beitragvon EyDu » Dienstag 16. Januar 2007, 15:19

Das was du suchst, entspricht wohl eher dem folgenden:

Code: Alles auswählen

class Mitarbeiter:
   def __init__(self, name, tel=0, fax=0):
      self.name = name
      self.tel = tel
      self.fax = fax


#Liste von Mitarbeitern erzeugen
ma = [Mitarbeiter("spam", 23, 1337), Mitarbeiter("eggs",42)]

#Ueber die Mitarbeiter laufen und deren Attribute ausgeben
for m in ma:
    print ma.name
    print ma.tel
    print ma.fax


Falls der Name eindeutig ist, könnte man das auch schön über ein Dictionary lösen.
capsule5
User
Beiträge: 28
Registriert: Sonntag 10. Dezember 2006, 18:49

Beitragvon capsule5 » Dienstag 16. Januar 2007, 15:39

Hallo EyDu,

Danke für die Antwort. Sollte es nicht "print m.name" statt "print ma.name" heissen?
Ich habe aber bei deiner Lösung keine Zuordnung von Name zu entsprechender Tel bzw. Fax.

Gruß
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Beitragvon sape » Dienstag 16. Januar 2007, 16:18

@capsule5:
Die Konvention für Klassennamen ist CamelCase und nur bei Konstanten werden alle Buchstaben groß geschrieben.

Gute Stil ist nicht Optional: http://www.python.org/dev/peps/pep-0008/

Ich habe aber bei deiner Lösung keine Zuordnung von Name zu entsprechender Tel bzw. Fax.
Hast du doch. ``m.name``, ``m.tel``, etc. Oder wie meinst du das?

EDIT: Du könntest dir aber auch eine Baumstruktur bauen, bei dem du dann z.B. nach Name, Tel. etc den Datensatz zurückgeben lässt. Das ganz lässt sich rekursiv Lössen.
capsule5
User
Beiträge: 28
Registriert: Sonntag 10. Dezember 2006, 18:49

Beitragvon capsule5 » Dienstag 16. Januar 2007, 16:54

Hallo sape,

ich will auf einzelne Daten zurückgreifen. Dazu ist "Mitarbeiter.Mueller.Tel" als sprechender Namen einfach besser geeignet als ma[2].tel.

Wie sieht denn eine rekursive Lösung aus?
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Beitragvon sape » Dienstag 16. Januar 2007, 17:04

Geht doch ohne Rekursion :) Hier mal mein Vorschlag.

Falls Fragen zum Code sind einfach Fragen. Der Code ist nicht Perfekt und sehr stark erweiterbar, aber so ungefähr würde ich das machen.

EDIT:
Code in LodgeIt ausgelagert.

Link: http://paste.pocoo.org/show/674/
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Beitragvon sape » Dienstag 16. Januar 2007, 17:20

Auf eine Datensatz kannst du dann mit der Methode ``get_filecard_by`` zurückgreifen. Wenn du dann z.B. den Datensatz von Müller haben willst, gibst du dann als zweiten Parameter ``'Müller'`` an und als dritten ``'name'`` (Defaultwert). Dan wird die Kartei durchsucht bis in ``self.name`` Müller gefunden wurde und dann der Datensatz zurückgegeben.

Falls keine Übereinstimmung gefunden wurde, wird ``None`` zurückgegeben.

Genauso kannst du dir einen Datensatz ``get_filecard_by``nach einer bestimmten Telefonnummer, etc zurückgeben lassen.

lg
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Beitragvon birkenfeld » Dienstag 16. Januar 2007, 17:25

Das ist ja fuerchterlich umstaendlich: ``associate_index.get_filecard_by("name", "Mueller")``.
Und nicht mal indiziert, also bei vielen Datensaetzen langsam.

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"]
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Beitragvon sape » Dienstag 16. Januar 2007, 17:32

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:
Jepp, stimmt. Aber das ganze ist dann nicht mehr so flexibel. Mit meiner Variante, kann man sich einen Datensatz auch zurückgeben lassen wo als Übereinstimmung z.B: die Telefonnummer gefunden wurde.

Aber bei ca. 100.000 Datensätzen ist meine Variante dennoch noch nicht so sehr "spürbar" langsam. Bei mehr als 100.000 Datensätzen würde ich dann ehe gleich SQLite verwenden anstatt meine Variante oder Dictionarys. Dafür ist sowas ja auch ursprünglich konzipiert wurden.

lg
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Beitragvon birkenfeld » Dienstag 16. Januar 2007, 17:38

Nach anderen Spalten kann man bei der Dictionary-Loesung ja durchaus auch suchen. Nur der Zugriff nach Name geht halt in O(1) statt O(n).

Was langsam und was schnell ist, ist immer eine Frage des Kontextes. Bei Problemen, wo Optimierung so einfach ist, spricht nichts dagegen, sie auch anzuwenden.
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Beitragvon sape » Dienstag 16. Januar 2007, 17:52

birkenfeld hat geschrieben:Nach anderen Spalten kann man bei der Dictionary-Loesung ja durchaus auch suchen. Nur der Zugriff nach Name geht halt in O(1) statt O(n).

Habs angepasst. Bei ``name`` wird der Key vom Dict genutzt, ansonsten werden die restlichen Spalten wie Tel. durchsucht.

Kannst dir ja mal kurz den Code anschauen und sagen ob du das so gemeint hattest.
http://paste.pocoo.org/show/678/

lg
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Beitragvon birkenfeld » Dienstag 16. Januar 2007, 17:55

Ja, fast. Das __getitem__ fehlt mir noch, und wenn du iteritems() verwendest nur um den Key wegzuwerfen kannst du auch gleich itervalues() hernehmen.
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Beitragvon sape » Dienstag 16. Januar 2007, 17:58

birkenfeld hat geschrieben:Ja, fast. Das __getitem__ fehlt mir noch,
Stimmt, werden ich gleich nachholen.
birkenfeld hat geschrieben: und wenn du iteritems() verwendest nur um den Key wegzuwerfen kannst du auch gleich itervalues() hernehmen.
Mist! Hast ja so recht :oops:
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Beitragvon sape » Dienstag 16. Januar 2007, 18:10

Fertig: http://paste.pocoo.org/show/681/


Hmm, wie würdest du das eigentlich machen? Ich habe bei ``__geitem__`` das so gemacht, falls der Key nicht existiert, wird None zurückgegeben, damit es analog zu ``get_filecard_by`` bleibt, dass ja auch None zurückgibt falls der Datensatz nicht existiert? Oder sollte ich da lieber den KeyError auslösen lassen und es nicht an dem "verhalten" an `get_filecard_by`` anpassen, bei nicht existentes eines Datensatzes?
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Beitragvon birkenfeld » Dienstag 16. Januar 2007, 18:12

Das ist dir als API-Designer ueberlassen und kommt zum Teil auch darauf an, was der Code, der die Klasse verwendet, mit dem Rueckgabewert anfaengt.
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder