Invalid Syntax an komischer Stelle | Telefonbuchklasse

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
CrackPod
User
Beiträge: 205
Registriert: Freitag 30. Juni 2006, 12:56

Hallo,

da ich mir aus Testzwecken ein Kommandozeilentelefonbuchprogramm progammieren will, hab ich mal eine Klasse entworfen(noch nich wirklich weit)
Jedoch bekomm ich eine Fehlermeldung:
$ python telefonbuch.py
File "telefonbuch.py", line 36
Mobil:\t %s' % (self.name, self.nName self.vName, self.strasse, self.plz, self.ort, self.privat, self.mobil)
^
SyntaxError: invalid syntax
Mein Code sieht folgendermaßen aus:

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: utf-8 -*-

class Eintrag:
    '''Diese Klasse erstellt Einträge für das Telefonbuch'''
    eintraege = 0
    
    def __init__ (self, nName = '', vName = '', strasse = '', plz = '', ort = '', privat = '', mobil = ''):
        if len(name) > 1:
            self.nName      = nName
        if len(vName) > 1:
            self.vName      = vName
        if len(strasse) > 1:
            self.strasse    = strasse
        if len(plz) > 1:
            self.plz        = plz
        if len(ort) > 1:
            self.ort        = ort
        if len(zuhause) > 1:
            self.privat     = privat
        if len(mobil) > 1:
            self.mobil      = mobil
        if len(self.name) > 1 and len(self.vName) > 1:
            self.name       = self.nName+','+self.vName

        Eintrag.eintraege += 1

    def __str__ (self):
        output = '###### Eintrag für: %s ###### \
                Name:\t %s \
                Vorname:\t %s \
                Straße:\t %s \
                Postleitzahl:\t %s \
                Ort:\t %s \
                Privat:\t %s \
                Mobil:\t %s' % (self.name, self.nName self.vName, self.strasse, self.plz, self.ort, self.privat, self.mobil)
        return output

einer = Eintrag('xy', '', 'irgendwo', 'der', 'ort', '2134444', '11654')
print einer
Kann mir einer sagen, warum der Fehler kommt und wie ich ihn beheben kann?
Wenn ich im falschen Bereich gelandet bin, dann tut mir das Leid, aber ich wusst jetz nich so genau, wohin damit...

Greetz
Zuletzt geändert von CrackPod am Sonntag 2. Juli 2006, 10:11, insgesamt 1-mal geändert.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

CrackPod hat geschrieben: Jedoch bekomm ich eine Fehlermeldung: [...] SyntaxError: invalid syntax
[...]
Kann mir einer sagen, warum der Fehler kommt und wie ich ihn beheben kann?
Hi CrackPod!

InvalidSyntax --> Du hast etwas so geschrieben, dass der Interpreter nicht daraus schlau wird. Du hattest einen Beistrich zwischen self.nName und self.vName vergessen. (Zeile 37)

Allerdings gibt es noch ein paar Ungereimtheiten. Die Klasse "Eintrag" stellt nur **einen** Eintrag des Telefonbuchs dar. Damit hat die Klassenvariable "eintraege" eigentlich nichts in diesem Eintrag zu suchen. Eine Zählung der Einträge sollte in der noch nicht existierenden Klasse "Telefonbuch" stattfinden. Dort kannst du deine Einträge sammeln und auch Buch über die Menge führen.

Der Code

Code: Alles auswählen

Eintrag.eintraege += 1
verändert nur die Klassenvariable. ---> Die nächste, neu erstellte, Klasseninstanz hat damit als Basis der Zählung einen korrekten Wert. Was passiert allerdings, wenn du eine Adresse löscht? So wird die Zählung nicht funktionieren. Lösung siehe vorherigen Absatz --> Klasse: Telefonbuch.

Wenn du in der Klasse Telefonbuch alle Einträge verwaltest, dann brauchst du nicht mehr über die Menge der Einträge Buch zu führen. Warum? Weil du dort wahrscheinlich deine Einträge in einer Liste oder in einem Dictionary verwalten wirst. Wenn ja, dann kannst du ja mit len() die Größe der Liste abfragen.

Dann habe ich noch etwas: Es bringt dir keinen Vorteil, wenn du die beim Initialisieren der Klasse NICHT übergebenen Variablen nicht in die Klasseninstanz schreibst.

Code: Alles auswählen

def __init__(self, vorname = "", nachname = "", ...):
    self.vorname = vorname
    self.nachname = nachname
So kannst du immer auf die Instanzvariablen self.vorname und self.nachname zugreifen. -- Ohne dass es einen Fehler gibt, wenn diese nicht existieren.

self.name -- das ist so eine fix codierte Sache, die dir Probleme machen wird, wenn sich bei irgendjemand der Nachname ändert. Und das ist bei einer Hochzeit ziemlich oft der Fall. Oder, was ist, wenn ich beim Eintragen den Vornamen noch nicht weiß. Diesen also erst später nachtrage? Besser wäre es, wenn du auf die Variable "self.name" verzichten würdest und diese immer neu zusammensetzt, wenn sie gebraucht wird.

Das kannst du ständig beim Gebrauch machen, oder du erstellst dir dafür eine Methode und evt. sogar ein Property.

Code: Alles auswählen

class Eintrag(object):
    
    ...
    ...
    
    def get_name(self):
        """
        Gibt den Namen, bestehend aus Vorname und Nachname zurück
        """
        
        return self.vorname + "," + self.nachname


    def __str__ (self):
        output = (
            "###### Eintrag fuer: %s ###### \n"
            "Name:\t %s \n"
            "Vorname:\t %s \n"
            "Strasse:\t %s \n"
            "Postleitzahl:\t %s \n"
            "Ort:\t %s \n"
            "Privat:\t %s \n"
            "Mobil:\t %s"
        ) % (
            self.get_name(), self.nName, self.vName, self.strasse, 
            self.plz, self.ort, self.privat, self.mobil
        )
        return output
Dein Ansatz ist schon mal nicht schlecht. Jetzt musst du nur noch an den Feinheiten arbeiten.

mfg
Gerold
:-)

Edit: Klammern vergessen ;-)
Zuletzt geändert von gerold am Sonntag 2. Juli 2006, 01:16, insgesamt 2-mal geändert.
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
CrackPod
User
Beiträge: 205
Registriert: Freitag 30. Juni 2006, 12:56

Ok, hab das jetz geändert:

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: utf-8 -*-

class Eintrag:
    '''Diese Klasse erstellt Einträge für das Telefonbuch'''
    
    def __init__ (self, nName = '', vName = '', strasse = '', plz = '', ort = '', privat = '', mobil = ''):
        self.nName      = nName
        self.vName      = vName
        self.strasse    = strasse
        self.plz        = plz
        self.ort        = ort
        self.privat     = privat
        self.mobil      = mobil

        Eintrag.eintraege += 1

    def getName(self):
        if len(self.nName) > 1 and len(self.vName) > 1:
            return self.nName + ',' + self.vName
        elif len(self.nName > 1):
            return self.nName
        else:
            return self.vName

    def __str__ (self):
        output = '###### Eintrag für: %s ###### \n\
                Name: %s \n\
                Vorname: %s \n\
                Straße: %s \n\
                Postleitzahl: %s \n\
                Ort: %s \n\
                Privat: %s \n\
                Mobil: %s\n' % (self.getName, self.nName, self.vName, self.strasse, self.plz, self.ort, self.privat, self.mobil)
        return output

einer = Eintrag('xy', '', 'irgendwo', 'der', 'ort', '2134444', '11654')
print einer
Meine Ausgabe sieht jedoch teilweise komisch aus :D irgendwas stimmt mit der Funktion nicht:
###### Eintrag für: <bound method Eintrag.getName of <__main__.Eintrag instance at 0xb7ddde8c>> ######
Name: xy
Vorname:
Straße: irgendwo
Postleitzahl: der
Ort: ort
Privat: 2134444
Mobil: 11654
Was is falsch?
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

CrackPod hat geschrieben:Was is falsch?
Hi CrackPod!

Das ging aber schnell. :-)

Ich habe in meinem Beispiel die Klammern vergessen:

Code: Alles auswählen

...self.get_name(), self.nName, self.vName, self.strasse,
mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
CrackPod
User
Beiträge: 205
Registriert: Freitag 30. Juni 2006, 12:56

Hab die Klammern angefügt. Wenn ich jedoch folgendes mache:

Code: Alles auswählen

jemand = Eintrag('name', 'vorname', 'str', 'plz', 'ort', 'privat', 'mobil')
einer = Eintrag('xy', '', 'irgendwo', 'der', 'ort', '2134444', '11654')
print jemand
print einer
Bekomm ich einen Fehler:
$ python telefonbuch.py
###### Eintrag für: name,vorname ######
Name: name
Vorname: vorname
Straße: str
Postleitzahl: plz
Ort: ort
Privat: privat
Mobil: mobil

Traceback (most recent call last):
File "telefonbuch.py", line 54, in ?
print einer
File "telefonbuch.py", line 25, in __str__
output = '###### Eintrag für: %s ###### \n\
File "telefonbuch.py", line 19, in getName
elif len(self.nName > 1):
TypeError: len() of unsized object
Was heist das? self.nName ist doch egtl instanziiert worden oder?
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

CrackPod hat geschrieben:Bekomm ich einen Fehler:
elif len(self.nName > 1):
TypeError: len() of unsized object
Hi CrackPod!

Da liegt nur eine falsch gesetzte Klammerung vor.

Ändere die Zeile nach

Code: Alles auswählen

elif len(self.nName) > 1:
Dann sollte es gehen.

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
CrackPod
User
Beiträge: 205
Registriert: Freitag 30. Juni 2006, 12:56

Mein Gott :oops: das is mir jetz peinlich :D
Naja liegt am Python anfänger^^ Andere Syntax schnellere Fehler.(Bin die Klammersetzung if(bedingung){bla} von Java udn PHP gewohnt:D)

Ich hab die Klasse jetz mal geändert:

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: utf-8 -*-

class Eintrag:
    '''Diese Klasse erstellt Einträge für das Telefonbuch'''
    
    def __init__ (self, nName = '', vName = '', strasse = '', plz = '', ort = '', privat = '', mobil = ''):
        self.nName      = nName
        self.vName      = vName
        self.strasse    = strasse
        self.plz        = plz
        self.ort        = ort
        self.privat     = privat
        self.mobil      = mobil
        self.data       = [self.nName, self.vName, self.strasse, self.plz, self.ort, self.privat, self.mobil]

    def getData (self):
        output = '###### Eintrag für: %s ###### \n\
    Name: %s \n\
    Vorname: %s \n\
    Straße: %s \n\
    Postleitzahl: %s \n\
    Ort: %s \n\
    Privat: %s \n\
    Mobil: %s\n' % (self.getName(), self.nName, self.vName, self.strasse, self.plz, self.ort, self.privat, self.mobil)

        return output

    def getName (self):
        '''Erstellt einen Namen für den Telefonbucheintrag'''

        if len(self.nName) > 1 and len(self.vName) > 1:
            return self.nName + ',' + self.vName
        elif len(self.nName) > 1:
            return self.nName
        else:
            return self.vName

    def getEntry (self):
        return self.data

class Telefonbuch:
    '''Diese Klasse verwaltet die Einträge des Telefonbuchs'''

    eintraege = 0

    def __init__ (self):
        '''Initialiesierung des Dictionaries, in dem alle Adressen gespeichert werden'''

        self.adressen = {}

    def addEntry (self, nName = '', vName = '', strasse = '', plz = '', ort = '', privat = '', mobil = ''):
        '''Fügt dem Telefonbuch einen Eintrag an'''

        newAdress = Eintrag(nName = '', vName = '', strasse = '', plz = '', ort = '', privat = '', mobil = '')

        self.adressen[nName] = newAdress.getEntry
        self.adressen[vName] = newAdress.getEntry

        Telefonbuch.eintraege += 1

    def getEntry(self, name):
        '''Versucht einen Eintrag aus dem Telefonbuch zu holen'''

        if self.adressen.has_key(name):
            return self.adressen[name].getData
        else:
            return 'Kein Eintrag unter diesem Namen gespeichert.'

telBuch = Telefonbuch()
telBuch.addEntry('name', 'vorname', 'str', 'plz', 'ort', 'privat', 'mobil')
telBuch.addEntry('xy', '', 'irgendwo', 'der', 'ort', '2134444', '11654')
print telBuch.getEntry('vorname')
print telBuch.getEntry('xy')
print telBuch.getEntry('name')
Meine Ausgabe:
$ python telefonbuch.py
Traceback (most recent call last):
File "telefonbuch.py", line 80, in ?
print telBuch.getEntry('vorname')
File "telefonbuch.py", line 66, in getEntry
return self.adressen[name].getData
AttributeError: 'function' object has no attribute 'getData'
Aber eigentlich müsste das doch funktionieren oder? Ich hab doch in das Dictionary die Instanz von Eintrag gelegt?!
Oder kann ich Eintrag nich aus Telefonbuch instanziieren?
EDIT:
Oh man, ich habs *kopfklatsch*
Lauter banale Fehler:

Code: Alles auswählen

return self.adressen[name].getData #Klammernpaar hat gefehlt
self.adressen[nName] = newAdress.getEntry #1. Klammern haben gefehlt. 2. getEntry ist sinnlos! Ich brauch die Instanz nich die Daten^^
newAdress = Eintrag(nName = '', vName = '', strasse = '', plz = '', ort = '', privat = '', mobil = '') #ich hab die Parameter faulheitshalber aus dem __init__ von Eintrag kopiert und vergessen Variablen draus zu machen :D
Ich glaub, das waren soziemlich alle Fehler, die ich gemacht hab
Benutzeravatar
newone_XXV.
User
Beiträge: 50
Registriert: Dienstag 20. Juni 2006, 15:03
Wohnort: Direkt vor meinem PC
Kontaktdaten:

Gut wenn Du´s schon hast.... Ansonsten bin ich gerade dabei gewesen, dass ganze mal ein bisschen schöner zu machen.... :wink:
CrackPod
User
Beiträge: 205
Registriert: Freitag 30. Juni 2006, 12:56

Bevor ihr meinen Code verschönet, lasst ihn mich bitte fertigstellen. Dann hab ich das verstanden usw (bin mit der Syntax und den Feinheiten von Python vertraut). Danach könnt ihr alles so ändern, wie ihr wollt und ich schau, dass ichs versteh :D
Hab aber mittlerweile ein neues Problem:

Code: Alles auswählen

if len(sys.argv) < 2:
    sys.argv[1] = '--help'

if sys.argv[1].startswith('--'):
    args = sys.argv[1][2:]
    if args == 'help':
        print 'Se haben die Hile gestartet.'
        print 'Mögliche Parameter: add, show, showall'
        print 'Parameter `add` fügt einen Eintrag in das Telefonbuch ein.'
        print 'Parameter `show` sucht und zeigt einen Eintrag aus dem Telefonbuch.'
        print 'Parameter `showall` zeigt alle Einträge des Telefonbuches.'
Damit will ich bewirken, dass, wenn jemand das Programm nur mit

Code: Alles auswählen

$ python telefonbuch.py
starten will die Hilfe angezeigt bekommt, da man Parameter beim Start übergeben muss.
Jedoch bekomm ich folgende Terminal ausgabe:
$ python telefonbuch.py
Traceback (most recent call last):
File "telefonbuch.py", line 77, in ?
sys.argv[1] = '--help'
IndexError: list assignment index out of range
$ python telefonbuch.py --help
Se haben die Hile gestartet.
Mögliche Parameter: add, show, showall
Parameter `add` fügt einen Eintrag in das Telefonbuch ein.
Parameter `show` sucht und zeigt einen Eintrag aus dem Telefonbuch.
Parameter `showall` zeigt alle Einträge des Telefonbuches.
Also stimmt irgendwas beim ersten If nich...
Benutzeravatar
DatenMetzgerX
User
Beiträge: 398
Registriert: Freitag 28. April 2006, 06:28
Wohnort: Zürich Seebach (CH)

Code: Alles auswählen

if len(sys.argv) > 2:  #Anderst rum ;)
    sys.argv[1] = '--help'
BlackJack

Du hast im ``if`` gerade geprüft ob die Liste `sys.argv` weniger als zwei, d.h. einen Eintrag hat. Der hat den Index 0. Einen zweiten Eintrag an Index 1 gibt's nicht, also kannst Du dem auch nichts zuweisen. Du kannst aber etwas an die Liste anhängen.

Code: Alles auswählen

In [5]: a = ['blah']

In [6]: a[0] = 'blubb'

In [7]: a
Out[7]: ['blubb']

In [8]: a[1] = 'hallo'
---------------------------------------------------------------------------
exceptions.IndexError         Traceback (most recent call last)

/home/marc/<ipython console>

IndexError: list assignment index out of range

In [9]: a.append('hallo')

In [10]: a
Out[10]: ['blubb', 'hallo']
CrackPod
User
Beiträge: 205
Registriert: Freitag 30. Juni 2006, 12:56

Achso ja^^ append :oops:
Wenn was mit [] is, dann sin das - in PHP - array und da kann man einfach so was anfügen. Hatt grad ne Sprachenverknüpfung :D
Danke
CrackPod
User
Beiträge: 205
Registriert: Freitag 30. Juni 2006, 12:56

Also neuer Statusbericht:
Ich will ja mit meinem Programm Kontakte speichern, löschen, alle anzeigen, einzelne anzeigen und alle löschen können.
Nur einen Kontakt anzeigen hat wunderwar funktioniert(eintragen logischerweise aus :wink:)
Alles löschen ging auch.
Aber was nicht ging, war alle anzeigen, die sin alle doppelt gekommen, weil ich jeweils den vor und den nachnahmen in eine variable gespeichert hab, damit man nach beiden suchen kann.
Jetz hab ich das umgeschrieben. Ich hab 2 Dictionaries:
Eines, in dem als key die vor und nachnamen stehen. Als wert haben sie eine id. Und das 2. Dict enthält als key die id und als wert eine referenz auf eine Eintragen instanz.
Nur irgendwie wird wenn cih einen 2. Kontakt einfüge der 1. überschrieben.
Schaut es euch einfach ma selber an:(hab nen nopaste dienst genommen, damit man nich so ewig rumscrollen muss)
http://nopaste.info/index.php?id=7e87f16508

Hoffe mir kann einer helfen
Greetz
BlackJack

Das kann so nicht klappen. Stell Dir vor Du möchtest die Brüder Hans und Klaus Meier speichern. Vereinfachen wir den Eintrag mal nur auf Vor- und Nachname und packen sie in Tupel. Was Du machst ist jeweils Vor- und Nachname als Schlüssel auf den kompletten Namen in `adressen` abzuspeichern:

Code: Alles auswählen

In [46]: adressen = dict()

In [47]: a = ('Hans', 'Meier')

In [48]: adressen['Hans'] = a

In [49]: adressen['Meier'] = a

In [50]: adressen
Out[50]: {'Hans': ('Hans', 'Meier'), 'Meier': ('Hans', 'Meier')}
Soweit so gut, aber nun:

Code: Alles auswählen

In [51]: a = ('Klaus', 'Meier')

In [52]: adressen['Klaus'] = a

In [53]: adressen['Meier'] = a

In [54]: adressen
Out[54]:
{'Hans': ('Hans', 'Meier'),
 'Klaus': ('Klaus', 'Meier'),
 'Meier': ('Klaus', 'Meier')}
Tja, jetzt hat der Klaus Meier den Eintrag von Hans Meier beim Nachnamen überschrieben. Das gleiche Problem tritt auf, wenn Du mehrere Leute mit gleichem Vornamen speicherst.

Wenn Du die Namen in einem Dictionary speichern möchtest, dann musst Du dafür sorgen, dass der Schlüssel eindeutig ist. Beim privaten Telefonbuch kommen die meisten Leute noch damit aus, wenn man einfach den kompletten Namen nimmt, aber es soll auch Leute geben die zwei Hans Meier kennen. Dann klappt auch das nicht mehr.

Ich würde die Namen einfach in einer Liste speichern. Beim persönlichen Telefonbuch ist selbst bei mehreren hundert Einträgen linearer Zugriff bzw. lineare Suche von der Laufzeit her noch vertretbar.
CrackPod
User
Beiträge: 205
Registriert: Freitag 30. Juni 2006, 12:56

naja das mit der Liste hab ich mir auch schon überlegt, aber das is auch schwierig, weil zu den namen ja egtl dann noch die instanz gespeichert werden müsste.
Naja ich könnte ja ein Dictionary folgenermaßen erstellen:

Code: Alles auswählen

a = dict()
neuerEintrag()
a['Hans,Meier'] = index
neuerEintrag()
a['Klaus,Meier'] = index
Wenn dann die Namen gesucht werden, kann ich die keys splitten und durchsuchen. Wenn alle ausgegeben werden sollen geht die lineare suche auch recht gschmeidig, weil ich mir egtl ne Kopie von den Werten der Namen machen könnte und die linear aufrufen kann.
Soweit zur Theorie :D
Geht das so? Oder hab ich wieder nen Logikfehler drin?
BlackJack

Ausser wenn es zwei Leute mit dem gleichen Namen gibt, könnte das funktionieren.

Aber wieso musst Du überhaupt die Namen auf die `Eintrag` Objekte abbilden? Du kannst doch auch gleich die Liste mit den `Eintrag` Objekten durchsuchen.

Einfaches Beispiel, das mit einer Adressenliste in der Telefonbuchklasse auskommt:

Code: Alles auswählen

class Entry(object):
    def __init__(self, name, surname, phone):
        self.name = name
        self.surname = surname
        self.phone = phone
    
    def __str__(self):
        return '%s, %s (%s)' % (self.surname, self.name, self.phone)
    
    def __cmp__(self, other):
        return cmp(self.surname, other.surname) or cmp(self.name, other.name)


class Phonebook(object):
    def __init__(self):
        self.addresses = list()
    
    def __len__(self):
        return len(self.addresses)
    
    def __iter__(self):
        return iter(self.addresses)
    
    def __str__(self):
        return '\n'.join(map(str, self))
    
    def add(self, entry):
        self.add_many([entry])
    
    def add_many(self, entries):
        self.addresses.extend(entries)
        self.addresses.sort()
    
    def search(self, string, fields=('surname',)):
        result = list()
        for entry in self:
            for field in fields:
                if string in getattr(entry, field):
                    result.append(entry)
                    break
        return result

phonebook = Phonebook()
phonebook.add_many((Entry('Klaus', 'Meier', '123-1'),
                    Entry('Hans', 'Meier', '123-2'),
                    Entry('Klaus', 'Schulz', '456'),
                    Entry('Max', 'Mustermann', '983')))

print phonebook
print map(str, phonebook.search('Meier'))
print map(str, phonebook.search('Klaus', ['name']))
print map(str, phonebook.search('123', ['phone']))
CrackPod
User
Beiträge: 205
Registriert: Freitag 30. Juni 2006, 12:56

wenn du mir den code noch kommentieren könntest, wär super :)
Hab da nich alles verstanden.
Für was is z.b. __iter__ oder __cmp__? Noch ne Frage nebenbei: Gibt es auch ein deutsches Manual? Bzw http://docs.python.org auf deutsch?
BlackJack

Die Methoden mit den zwei Unterstrichen vorne und hinten sind dazu da, das man Klassen schreiben kann, die sich ähnlich wie die eingebauten Datentypen verhalten. Meistens haben sie den gleichen Namen wie eingebaute Funktionen, die dann eben diese Methoden aufrufen.

`__str__` wird zum Beispiel aufgerufen wenn man die `str()` Funktion auf ein Objekt anwendet oder das Objekt mit `%s` in einer Zeichenkette formatiert oder mit ``print`` ausgibt.

`__iter__` wird von der `iter()` Funktion aufgerufen und wenn man das Objekt nach dem ``in`` einer ``for``-Schleife platziert. Die Methode muss einen Iterator zurückgeben.

Da ein `Entry` Objekt "weiss" wie es in eine Zeichenkette umgewandelt werden kann und ein `Phonebook` Objekt "iterierbar" ist, also in einer Schleife die enthaltenden `Entry` Objekte zurückgibt, kann man zum Beispiel so etwas schreiben:

Code: Alles auswählen

for entry in phonebook:
    print entry
Die `__cmp__()` Methode wird aufgerufen wenn man die `cmp()` Funktion anwendet und auch bei Vergleichsoperationen wie `==`, `!=`, `>`, `<`, `>=` und `<=`. So kann man eigenen Datentypen eine Ordnung geben. Man kann `Entry` Objekte also miteinander vergleichen. Und weil man das kann, ist es möglich mit der `sort()` Methode auf Listen, eine Liste von Telefonbucheinträgen zu sortieren.
Antworten