Fehlermeldung bei der __str__()-Methode

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
Dexter1997
User
Beiträge: 92
Registriert: Sonntag 2. Dezember 2012, 21:13

Die __str__Methode bestimmt meines Wissens nach, was der Computer ausgeben soll, wenn im Code mittels print-Anweisung befohlen wird ein Objekt auszugeben.
Wenn ich jedoch folgenden Code versuche auszuführen, kommt ab dem __str__Teil eine Fehlermeldung.

Code: Alles auswählen

class Bank_Konto:

    def __init__(self, Name, Kontonummer, Kontostand):
        self.Name = Name
        self.Kontonummer = Kontonummer
        self.Kontostand = Kontostand

    def __str__(self):
        print "Name des Kontoinhabers: " + str(self.Name)
        print "Kontonummer: " + str(self.Kontonummer)

    def Kontostand_anzeigen(self):
        print "Kontostand: " + str(self.Kontostand)

    def Einzahlen_oder_Auszahlen(self, Betrag):
        print "[1] Einzahlen"
        print "[2] Auszahlen"
        Auswahl = int(raw_input("Gib die entsprechende Zahl ein"))
        if Auswahl == 1:
            Einzahlen = int(raw_input("Wieviel moechtest du einzahlen?"))
            self.Kontostand += Einzahlen
        elif Auswahl == 2:
            Auszahlen = int(raw_input("Wieviel moechtest du auszahlen?"))
            self.Kontostand -= Auszahlen

Name_Konto = raw_input("Wie soll dein Konto heissen?")
Konto_Benutzer = Bank_Konto(Name_Konto, 123456, 1000000)
print Konto_Benutzer
Fehlermeldung:
Traceback (most recent call last):
File "C:\Dokumente und Einstellungen\Gastkonto\Desktop\Python\Programme\Buch\Kapitel14_Aufgabe1.py", line 28, in <module>
print Konto_Benutzer
TypeError: __str__ returned non-string (type NoneType)

(Das ist eine Aufgabe aus einem Buch)
Könnt ihr mir helfen das Problem zu lösen?
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Hallo.

Steht doch da: __str__ gibt keinen String zurück.
Das Leben ist wie ein Tennisball.
Dexter1997
User
Beiträge: 92
Registriert: Sonntag 2. Dezember 2012, 21:13

Problem gelößt^^
Die __str__Methode verlangt von mir die Nachricht an einen Namen zu binden und diese dann mittels return an den aufrufer zurueckzugeben
danke an eydu
BlackJack

@Dexter1@Dexter1997: Die `__str__()`-Methode verlangt ganz bestimmt nicht, dass etwas an einen Namen gebunden wird.

„Bankkonto” ist *ein* Wort, dementsprechend müsste die Klasse auch so heissen. Und ich glaube auf den Style Guide for Python Code wurde schon mehrfach verwiesen — die Methoden- und Attributnamen entsprechen dem wieder nicht.

An `Konto_Benutzer` wird kein Kontobenutzer gebunden, damit ist der Name falsch gewählt. `Name_Konto` ist auch irgendwie komisch für einen Kontonamen — es sei denn man heisst Yoda. ;-)

Die Klasse ist unschön, da sie das Konto-Objekt massiv mit der Benutzerinteraktion vermischt.
Dexter1997
User
Beiträge: 92
Registriert: Sonntag 2. Dezember 2012, 21:13

@Dexter1@Dexter1997: Die `__str__()`-Methode verlangt ganz bestimmt nicht, dass etwas an einen Namen gebunden wird.


Aber genau DAS hat geklappt. Was wäre denn eine genaue Beschreibung von dem was diese Methode tut
Und ich glaube auf den Style Guide for Python Code wurde schon mehrfach verwiesen — die Methoden- und Attributnamen entsprechen dem wieder nicht.
Das stimmt. Ich war bisher nur zu faul mir ein englisches Tutorial zu Gemüte zu führen. Man muss so schon soviel lernen >.< Ich werd's aber noch nachholen
An `Konto_Benutzer` wird kein Kontobenutzer gebunden, damit ist der Name falsch gewählt. `Name_Konto` ist auch irgendwie komisch für einen Kontonamen — es sei denn man heisst Yoda. ;-)
Das Problem ist auch die Aufgabe. Ich habe keinen Plan von Konten xD, wie sie sich verhalten oder was man ihnen für Namen gibt.
Die Klasse ist unschön, da sie das Konto-Objekt massiv mit der Benutzerinteraktion vermischt.
Und wo siehst du darin ein Problem? Ich lass mich gern eines besseren belehren:)
BlackJack

@Dexter1997: Die `__str__()`-Methode *muss* ein Objekt vom Typ `str` zurück geben. Das ist letztlich das Einzige was von der Laufzeitumgebung verlangt wird. Der Rückgabewert *sollte* eine für Endbenutzer gedachte Zeichenkettendarstellung des Objekts enthalten. Das verlangt die Dokumentation. Weder technisch noch per Konvention wird irgendwo verlangt ob und was innerhalb der Methode an irgendwelche lokalen Namen gebunden wird. Das kann und sollte man machen wenn es sinnvoll ist. Man muss es aber nicht wenn es nicht sinnvoll ist.

Man sollte Objekten Namen geben, die beschreiben wofür das Objekt im Programmkontext steht. Wenn es sich allgemein um ein Konto handelt, dann halt `konto`. Und nicht `kontobenutzer`. Denn ein Konto ist nun einmal kein Kontobenutzer. Hier würde auch der Style-Guide helfen, denn wenn man eine Klasse mit einem passenden Namen hat, dann ergibt sich daraus automatisch ein generischer Name für ein Exemplar dieses Datentyps. Wenn einem im gegebenen Kontext kein passenderer Name einfällt.

Das Problem bei der Vermischung von Geschäftslogik und Benutzerinteraktion ist, dass diese beiden Sachen getrennt und austauschbar sein sollten. Stell Dir vor Du hast eine komplette Bank in solchen Klassen geschrieben die über das Terminal per Text mit dem Benutzer interagiert. Und jetzt soll das auf eine grafische Oberfläche umgestellt werden. Die Programmlogik für Konten und so weiter ändert sich da ja eigentlich nicht, trotzdem müsste man die Klassen alle ändern, statt die Geschäftslogik wiederzuverwenden und nur den Teil der Benutzerinteraktion zusätzlich zu schreiben.

Selbst wenn man nur *eine* Art der Benutzerinteraktion verwendet, können verschiedene Arten von Benutzern unterschiedliche Dinge mit den Objekten anstellen. Ein Bankangestellter greift anders auf Konten zu als ein Kontoinhaber, oder jemand der nur eine bestimmte Vollmacht über ein Konto hat. Dann gibt es Automatismen wie Daueraufträge oder Einzugsermächtigungen von aussen. Oder den Zugriff über einen Geldautomaten. Das sind alles Sachen, welche die Grundfunktionalitäten eines Kontos verwenden, aber nicht Teil des Kontos selber sind.
Antworten