Ach herrje, das sieht aus wie jemand der von Java oder so kommt und das in Python genau so machen will, wie er es von dort kennt.
Man schreibt nicht ein Modul pro Klasse, denn Module sind dazu da um mehrere Funktionen und Klassen zusammenzufassen. Wenn jedes Modul nur eine einzige Klasse enthält, dann verschenkt man das Organisationsmittel „Modul“ unnötigerweise.
Die `object.__str__()`-Methode greift auf `__repr__()` zurück. Es macht also keinen Sinn `__repr__()` und `__str__()` zu implementieren und da genau den gleichen Code rein zu schreiben, denn das genau gleiche Ergebnis erhält man, wenn man nur `__repr__()` implementiert.
Die doppelten führenden Unterstriche Bei Namen und Nummer bedeuten nicht das was der Autor denkt. Das sollte nur ein führender Unterstrich sein. Da es dann aber triviale Getter- und Setter-Methoden gibt, sollte es aber gar keinen Unterstrich geben, denn in dem Fall greift man einfach direkt auf die Attribute zu. Triviale Getter/Setter macht man in Python nicht. Das macht man in Programmiersprachen die keine berechneten Attribute a.k.a. „Properties“ kennen. Python hat so etwas aber.
Damit schrumpft die Klasse dann hieraus zusammen:
Code: Alles auswählen
class TelefonbuchEintrag:
def __init__(self, name, nummer):
self.name = name
self.nummer = nummer
def __repr__(self):
return self.name
Was hier nicht gut ist, ist `__repr__()` weil das die Methode ist, die eine Zeichenkettenrepräsentation erstellen soll, die dem Programmierer bei der Fehlersuche helfen soll. Die `object`-Implementierung hat darum den Datentyp und eine eindeutige Hexadezimalzahl in der Darstellung. So weiss man *was* das ist, und kann alle Objekte von diesem Typ in der `repr()`-Darstellung voneinander unterscheiden. Wenn man das überschreibt, sollte man das so machen, dass ein Programmierer etwas damit anfangen kann. Zum Beispiel in dem man mehr Informationen zu dem Typ und der ID hinzufügt. Wenn der Rückgabewert nicht in <…> einfasst ist, dann ist er in der Regel in einer Form, die man wieder in Python-Quelltext einfügen kann. Das könnte dann so aussehen:
Code: Alles auswählen
class TelefonbuchEintrag:
def __init__(self, name, nummer):
self.name = name
self.nummer = nummer
def __repr__(self):
return f"{self.__class__.__name__}({self.name!r}, {self.nummer!r})"
Das sieht dann so aus:
Code: Alles auswählen
In [2]: eintrag = TelefonbuchEintrag("Peter Rabbit", "555-1234567")
In [3]: eintrag
Out[3]: TelefonbuchEintrag('Peter Rabbit', '555-1234567')
Namen werden in Python klein_mit_unterstrichen geschrieben. Ausnahmen sind Konstanten (KOMPLETT_GROSS) und Klassen (PascalCase). `Telefonbuch` sollte also `telefonbuch` heissen.
``while`` ist keine Funktion, das sollte man nicht so schreiben als wäre es eine. Da gehört ein Leerzeichen hinter das Schlüsselwort. Und die Klammern um das `True` sind überflüssig.
Man sollte keine kryptischen Abkürzungen als Namen verwenden. `inp` sollte wohl `input` heissen, so heisst aber schon die Funktion. `eingabe` wäre ein sinnvoller Name wenn da schon Deutsch für die Bezeichner verwendet wird. Im Englischen böte sich `answer` an.
Das die Vergleiche der Antwort in der Reihenfolge c, a, b erfolgen, ist ein bisschen verwirrend IMHO.
`exit()` gibt es so eigentlich gar nicht. Das würde man aus `sys` importieren müssen. Aber `sys.exit()` sollte man nur verwenden, wenn man zumindest potentiell einen anderen Rückgabecode als 0 an den Aufrufer des Programms zurückgeben will. Sonst ist das eher der Versuch sich darum zu drücken den Programmablauf sauber zu gestalten. Man könnte hier beispielsweise einfach mit ``break`` die Schleife verlassen.
Da `inp` nur einen der getesteten Werte haben kann, würde man hier für zwei der Tests auf diese Bedingung(en) ``elif`` statt ``if`` nehmen. Dann wird nicht unnötig getestet, und man kann auch einen ``else``-Zweig ans Ende setzen, mit einer Fehlermeldung.
Code: Alles auswählen
#!/usr/bin/env python3
class TelefonbuchEintrag:
def __init__(self, name, nummer):
self.name = name
self.nummer = nummer
def __repr__(self):
return f"{self.__class__.__name__}({self.name!r}, {self.nummer!r})"
def main():
telefonbuch = []
while True:
eingabe = input(
"Was möchtest Du tun?\n"
" a) Telefonbuch ausgeben?\n"
" b) Eintrag hinzufügen\n"
" c) Programm verlassen\n"
)
if eingabe == "a":
print(telefonbuch)
elif eingabe == "b":
name = input("Gib den Namen ein: ")
nummer = input("Gib die Nummer ein: ")
telefonbuch.append(TelefonbuchEintrag(name, nummer))
elif eingabe == "c":
break
else:
print(f"Fehler! Ungültige Eingabe {eingabe!r}.")
if __name__ == "__main__":
main()
Beide Fehler in den Bildern kann ich so nicht erklären. Der Editor/die IDE die Du da verwendest wird aber irgendwo noch erklären warum das unterkringelt ist. Beides sind aber wohl Warnungen und keine Fehler, denn die IDEs die ich kenne unterkringeln Fehler rot. Ansonsten müsstest Du realen Code als Quelltext zeigen und nicht als Bild(er).