Klasseninstanz interaktiv erstellen

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
Benutzeravatar
Drake
User
Beiträge: 71
Registriert: Mittwoch 14. März 2007, 15:48
Wohnort: Bremen
Kontaktdaten:

Hallo liebes Forum,

ich scheine hier gerade unheimlich auf dem Schlauch zu stehen.

Ich spiele momentan ein bisschen mit Python rum und würde gerne eine Instanz einer Klasse "interaktiv" erstellen lassen.

Code: Alles auswählen

from random import randint

class Konto:
    
    def __init__(self, name, kNr, kontostand = 0):
        
        self.name = name
        self.kNr  = kNr
        self.kontostand = kontostand
        
    def einzahlen(self, betrag):
        
        self.kontostand = self.kontostand + betrag
        
    def abheben(self, betrag):
        
        self.kontostand = self.kontostand - betrag
        
    def getValue(self):
        
        return self.kontostand

print ("""
Was möchtest du tun?

1.) Konto eröffnen
2.) Einzahlen
3.) Abheben
4.) Kontostand abfragen""")

iAnswer = int(input("\nAuswahl: "))

if (iAnswer == 1):
    name = input("\nWie ist dein Name? ")
    name = Konto()

elif ( iAnswer == 2):
    print ("2 gewählt!") 


Das ganze ist nur ein billiger Schnipsel, absolut nichtssagend, allerdings stört mich dieses Problem.
Wenn ich das ganze so realisiere, ist es schlichtweg falsch, weil die variable "name" sich jedesmal überschreiben würde und keine weitere Instanz zustande kommen würde.

Bin ich einfach gerade blind, oder ist es doch etwas anspruchsvoller?

Vielen Dank
Marc
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

@Drake:
Das Programm ist so nichtmal lauffähig, da Du Konto() ohne Parameter aufrufst.

Zur eigentlichen Frage - wenn Du mehrere Konten verwalten willst, brauchst Du eine Struktur, die die Konten vorhält (aka Bank). Das geht mit Containertypen, z.B. mit einem Wörterbuch:

Code: Alles auswählen

bank = {<kontonummer>: konto}
BlackJack

@Drake: Weitere Anmerkungen: Man sollte keine Abkürzungen bei Namen verwenden wenn die nicht allgemein bekannt sind. `kNr` sollte also `kontonummer` heissen.

Bei den Namen deutsch und englisch zu mischen ist komisch und fehleranfällig, weil man nie so genau weiss ob man nun einen deuschen oder einen englischen Namen benutzen muss, und zudem noch die Gefahr besteht das man irgendwann zwei Namen hat die vom Wort das gleiche bedeuten im Programm aber für unterschiedliche Dinge stehen. Das ist verwirrend.

Namenskonvention für alles ausser Klassen und Konstanten in Python sind `kleinbuchstaben_mit_unterstrichen`. Das und anderes steht im Style Guide for Python Code.

Triviale Getter braucht man in Python nicht, also `Konto.getValue()` ist überflüssig.

Typinformationen und dann auch noch als Präfix haben in Namen nichts zu suchen. Wenn der Leser wissen soll das etwas eine Zahl ist, dann nennt man das nicht `iAnswer` sondern `number`. Dann wissen das sogar Leser die mit dem `i` nichts anfangen können.

Klammern um Bedingungen bei ``if`` & Co sind überflüssig.

Auf Modulebene sollte kein Code stehen der nicht Konstanten, Funktionen, oder Klassen definiert. Das Hauptprogramm gehört in eine Funktion die mit folgendem Idiom davor geschützt wird ausgeführt zu werden wenn man das Modul per ``import`` Importiert statt es auszuführen:

Code: Alles auswählen

if __name__ == '__main__':
    main()
Dann kann man das Modul importieren, zum testen, Code wiederverwenden, und einige Werkzeuge erwarten ebenfalls das man ein Modul ohne Seiteneffekte importieren kann.
Benutzeravatar
MagBen
User
Beiträge: 799
Registriert: Freitag 6. Juni 2014, 05:56
Wohnort: Bremen
Kontaktdaten:

Python eignet sich hervorragend zum interaktiven Rumspielen. Diese Interaktion muss aber gar nicht groß programmiert werden. Spiele einfach ein bisschen in einer Python Shell mit den Objekten Deiner Klassen herum. Damit das auch Spaß macht, solltest Du unbedingt die beiden Methoden __str__ und __repr__ implementieren. Auch Klassen- und Methoden-Kommentare machen sich dabei ganz gut. Das könnte z.B. so gehn:

Code: Alles auswählen

# -*- coding: utf-8 -*-

from random import randint

class Konto:
    """Eine primitive Konto-Simulation"""
   
    def __init__(self, name="Bitte den Namen einfügen", kNr=None, kontostand = 0):
        """
        @param name: wenn weggelassen, dann sollte dieser später gesetzt werden.
        @param kNr: wird automatisch generiert, wenn weggelassen
        """
        
        self.name = name
        self.kNr  = kNr if kNr else randint(1e9,1e10-1)
        self.kontostand = kontostand
       
    def einzahlen(self, betrag):
        """Wie der Name schon sagt es wird eingezahlt (blöde Frage)"""
        self.kontostand = self.kontostand + betrag
       
    def abheben(self, betrag):
        self.kontostand = self.kontostand - betrag
        
    def ueberweisen(self, zielKonto, betrag):
        self.abheben(betrag)
        zielKonto.einzahlen(betrag)
       
    def getValue(self):
        return self.kontostand
    
    def __str__(self):
        return "Konto %i, <%s>, %+.2f EUR" % (self.kNr, self.name, self.kontostand)
    
    def __repr__(self):
        return "Konto(name='%s', kNr=%i, kontostand=%+.2f)" % (self.name, self.kNr, self.kontostand)
Diesen Code speicherst Du in einer Datei "konto.py" ab. Dann gehst Du in einer Konsole in das Verzeichnis von konto.py und rufst "python" auf. Jetzt kann die Interaktion beginnen, alles was in den Zeilen mit >>> kommt sind meine Eingaben (d.h. Interkationen):

Code: Alles auswählen

>>> from konto import Konto
>>> a = Konto("A. Grtsch")
>>> help(a)
Help on instance of Konto in module konto:

class Konto
 |  Eine primitive Konto-Simulation
 |  
 |  Methods defined here:
 |  
 |  __init__(self, name='Bitte den Namen einf\xc3\xbcgen', kNr=None, kontostand=0)
 |      @param name: wenn weggelassen, dann sollte dieser später gesetzt werden.
 |      @param kNr: wird automatisch generiert, wenn weggelassen
 |  
 |  __repr__(self)
 |  
 |  __str__(self)
 |  
 |  abheben(self, betrag)
 |  
 |  einzahlen(self, betrag)
 |      Wie der Name schon sagt es wird eingezahlt (blöde Frage)
 |  
 |  getValue(self)
 |  
 |  ueberweisen(self, zielKonto, betrag)
(END) (mit der Taste q kommt man hier raus)

>>> help(a.einzahlen)
Help on method einzahlen in module konto:

einzahlen(self, betrag) method of konto.Konto instance
    Wie der Name schon sagt es wird eingezahlt (blöde Frage)
(END) (mit der Taste q kommt man hier raus)

>>> a.einzahlen(250)
>>> a
Konto(name='A. Grtsch', kNr=8300497957, kontostand=+250.00)
>>> b = Konto(Y. Hrz)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'Y' is not defined (Fehlerhandling funktioniert schon)
>>> b = Konto("Y. Hrz")
>>> a.ueberweisen(b, 300)
>>> print(a)
Konto 8300497957, <A. Grtsch>, -50.00 EUR
>>> print(b)
Konto 5407077965, <Y. Hrz>, +300.00 EUR
a fool with a tool is still a fool, www.magben.de, YouTube
Antworten