Anfängerfrage: n - Objekte während der Laufzeit instanzieren

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
angwedh
User
Beiträge: 20
Registriert: Dienstag 16. März 2010, 08:04

Hallo Zusammen
Ich bin blutiger Programmier/Pythonanfänger wagte mich nun aber bereits an mein erstes objektorientierte Programm/Script. Ich versuchte etwas über die Suchfunktion zu finden, fand aber nichts. Ich denke, ich brauchte wohl das falsche Vokabular.

Dabei geht es um die Verwaltung von Konten. Ich schrieb also eine Klasse Konto mit den Attributen Name, Betrag, Zins. Nun soll der User während der Laufzeit des Programmes neue Konten, also Objekte der Klasse Konto erstellen. Jedoch ist nicht vorgegeben, wie viele Konten er instanzieren will.

Wie kann ich dies in Python verwirklichen? Sprich ich muss Namen x(1), x(2), x(3), ..., x(n) erstellen können um dann immer ein neus objekt im Stil: x(n) = Konto(Bank, Betrag, Zins) generieren lassen.

Daraus ergibt sich meine zweite Frage: Wie verwalte ich dann am besten die verschiedenen Objekte? In einem Dict, in dem der Kontoname und das dazugehörige Objekt gespeichert wurde?

Vielen Dank bereits jetzt für die Antworten!

angwedh
.robert
User
Beiträge: 274
Registriert: Mittwoch 25. April 2007, 17:59

Hi,

ich empfehle dir dringendst, ein Python Tutorial oder Einsteigerbuch zu lesen. Das ist absolut basic.
Starte z.B. da: http://wiki.python-forum.de/Tutorial

Und als kleiner Hinweis: wenn du dict schon kennst, könntest du dir auch list mal ansehen...

Gruß,
r.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Hallo und willkommen im Forum!

Du hast schon ganz richtig erkannt, dass Namen generieren nicht wirklich schön ist. Der Richtige Ansatz sind hier Listen oder Dictionaries. Welche Lösung du wählst ist ein wenig abhängig davon, was du später auf den Daten machen möchtest.

Wenn du es noch nicht getan hast, solltest du dir noch das Python-Tutorial durchlesen, bzw. es auch verstehen. Im Prinzip brauchst du für diese Aufgabe nur eine Schleife in welcher die Abfragen durchgeführt werden.

Zeig mal deinen bisher zum Problem vorhandenen Code, damit lässt sich am besten arbeiten.

Sebastian
Das Leben ist wie ein Tennisball.
angwedh
User
Beiträge: 20
Registriert: Dienstag 16. März 2010, 08:04

Vielen Dank für die Antworten!
Ich bin bereits in Besitz eines Einsteigerbuches, auch fast alles durchgelesen, jedoch das Kap. mit dict. Übersprungen, da ich dieses lesen wollte, sobald ich es benötige. Ich schrieb in meiner Vergangenheit bereits ein paar "Progrämmchen", jedoch noch keines objektorientiert, weswegen ich den Zusammenhang mit den dict. nicht sah.

=> Ich werde nun das Kapitel aber schläunigst durcharbeiten.

@EyDu: Bis jetzt hatte ich noch gar keinen Code geschrieben, sondern mehr theoretisch durchdacht, auf was ich alles stossen könnte. Habe nun das ganze kurz geschrieben, ist sicher nicht gerade professionell aber bis jetzt funktionierst :? (Ich habe diese "Struktur" gewählt, da ich Schritt für Schritt das Programm verbessern/verfeinern will z.B. Speichern/Laden der Objekte, darstellen in einer Übersicht, grafische Benutzeroberfäche etc., ist halt ein Übungsprojekt)

Code: Alles auswählen

#konto.py

#Klassendefinitionen
class Konto(object):                #Konto-Klasse

    def __init__(self, name, betrag, zins):
        self.__name = name
        self.__betrag = betrag
        self.__zins = zins

    def getName(self):
        return self.__name

class UserInterface(object):        #Benutzereingabe, später GUI

    def __init__(self):
        self.__run()

    def __run(self):                #Abfrage, was man machen will
        print("Willkommen beim Konto-Manager")
        x = 'n'

        while x == 'n':
            f = int(input("Was wollen Sie tun: 1 = neues Konto, 2 = Konto ansehen, 3 = Konto speichern?"))
            if f == 1:
                self.__newKonto()
            elif f == 2:
                print("Leider wird diese Funktion noch nicht unterstützt")
            elif f == 3:
                print("Leider wird diese Funktion noch nicht unterstützt")
                
            x = input("Beenden? (j/n)")
            
    def __newKonto(self):           #Sollte ein neues Objekt der Klasse Konto generieren
        name = input("Geben Sie den Namen des Konto ein: ")
        betrag = int(input("Wie viel ist auf dem Konto: "))
        zins = float(input("Wie hoch ist der Zinssatz: "))

        #Hier komme ich dann nicht mehr weiter!

        
#Hauptprogramm
start = UserInterface()
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Wie heißt denn Dein Buch? Wenn ich so Sachen sehe wie "__name" oder auch "getName" denkt man schnell ans Open Book von Galileo :-D

Mal im Ernst: Furchtbares Design. Ist nicht Deine Schuld als Anfänger, sondern muss man wohl dem Buch ankreiden, was Du da liest. Die Klasse UserInterface ist vollkommen "missbraucht" (Man startet doch keine Endlosschleife aus __init__) Aber so oder so ist die komplett überflüssig Das ganze sollte man eher in eine Funktion packen. Auch wenn man ein Programm Schritt für Schritt verfeinern will, sollte man es soch sinnvoll angehen. Und Klassen sind eben kein Selbstzweck. Fürs Konto mag das noch ok sein; aber getter und setter sind vollkommen sinnlos in Python.

Sieh Dir mal PEP8 an; dein Code hält sich an einigen Stellen nicht wirklich dran (CamelCase / mixedCase bei Methoden z.B. gibts in Python nur in Ausnahemfällen).
angwedh
User
Beiträge: 20
Registriert: Dienstag 16. März 2010, 08:04

Hallo
Danke für die Kritik, werde sie mir zu Herzen nehmen.
Gekauft hatte ich mir "Objektorientiertes Programmieren mit Python3" bei mitp. Ob nun meine Bezeichnungen und Benennungen daraus kommen, kann ich leider gerade nicht sagen, habe das Buch nicht zur Hand. Jedoch lies ich auch viel im www, von wo ich das evtl. sonst noch etwas aufgeschnappt hatte. Mit dem Buch bin ich ziemlich zufrieden, das Problem ist halt, wie bei jedem "Anfängerbuch" das es nicht viel komplexere praxisnahe Beispiele hat, jedoch war dies das Buch mit den meisten Praxiscodes (war auch eines meiner Kaufkriterien) weswegen ich dieses Buch nun nicht anschwärzen möchte!

Wie gesagt, als oop-Neuling begreiffe ich noch nicht viel vom Design, ich ging davon aus, dass man dann alles über Klassen steuert.

Gruss
angwedh
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Naja, nur weil man OO programmiert heißt das nicht, dass man zwangsläufig etwas mit Klassen macht - dazu hatten wir erst grad wieder nen Thread hier ;-) Zumindest heißt es nicht, dass man alles mit Klassen zupflastern muss.

Schau Dir doch mal Deine UserInterface Klasse an. Was macht die eigentlich? Im Endeffekt startest Du von der __init__-Methode durch in eine obskure __run() Methode, die prinzipiell endlos weiterläuft. Du verwaltest keine Zustände und hast sonst auch keine sinnvollen Aktionen, die von außen auf Objekten dieser Klasse stattfinden (Du müßtest ja nicht einmal einen Namen an UserInterface() binden - du fängst damit ja nichts weiter an.)

Ich würde diese Klasse ersatzlos streichen und das ganze über Funktionen lösen - denn Deine Klasse bietet der __run()-Methode nichts, was nicht auch eine Funktion namens "run" erledigen könnte.

Den "hier komme ich nicht weiter"-Kommentar kapiere ich nicht. Du müßtest doch jetzt einfach ein Objekt von Konto erstellen und an einen Namen binden (oder im Falle der Funktion dieses Objekt zurückliefern).
angwedh
User
Beiträge: 20
Registriert: Dienstag 16. März 2010, 08:04

Hallo Hyperion
Dass meine UserInterface Klasse nichts macht, ist mir bewusst, ich habe dies anhand einem Beispiel abgeleitet, in dem über einer solchen Klasse dann mit tkinter die GUI programmiert wurde, was in einem späteren Zeitpunkt auf meiner ToDo-Liste steht.

Ich bin mir sicher, dass ich OOP noch nicht ganz begriffen habe, arbeite jedoch daran :)

Das Problem beim "hier komme ich nicht weiter" ist, dass ich nicht nur ein Konto verwalten möchte, sondern n-Konten, das heist zum Beispiel eines bei der Bank A, eines bei der Bank B etc.

Bei der Erstellung einer neuen Instanz der Klasse Konto muss ich ja diesem Objekt einen Namen gebe im Stil von: kontoa = Konto(Name, Betrag, Zins). Nun brauche ich doch aber für das Konto bei der Bank B einen neuen Objektnamen, z.B. kontob = Konto(Name, Betrag, Zins).

Ich denke aber dass ich mithilfe eines Dicts weiterkomme, bin zur Zeit nur etwas zu Beschäftig anderweitig.

Gruss
angwedh
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Also da würde sich eine Liste anbieten - ein dict ist eher dann geeignet, wenn Du einen Schlüssel hast, mit Hilfe dessen Du später wieder auf einen Datensatz gezielt zugreifen kannst. Bei einer list müßtest Du ja sonst alle durchgehen...
angwedh
User
Beiträge: 20
Registriert: Dienstag 16. März 2010, 08:04

Guten Morgen
Ich habe nun meinen Code abgeändert, in der Hoffnung, dass er nicht mehr so viel Kritik erhält (falls doch um so besser, dann lerne ich mehr :D ).

Ich habe mich jetzt für ein Dict entschieden, werde es aber wohl noch abändern. Damit ich dann mithilfe des Attributes "name" zugreifen kann auf die einzelnen Einträge, würde ich dann noch ein Dict erstellen, im Stil Key: kontos[x].name und Value: kontos[x].

Hier mein Code, wie gesagt, Kritik erwünscht, ob es nun über meinen Stil ist ober ob man etwas anders initialisiert:

Code: Alles auswählen

#konto.py

#Klassendefinitionen
class Account(object):                #Konto-Klasse

    def __init__(self, name, amount, interest):
        self.name = name
        self.amount = amount
        self.interest = interest


#Funktionen
def run(accounts):
    print("Willkommen beim Konto-Manager")
    x = 'n'
    k = 0
    while x == 'n':
        f = int(input("Was wollen Sie tun: 1 = neues Konto, 2 = Konto ansehen, 3 = Konto speichern?"))
        if f == 1:
            accounts[k] = new_account()
            k += 1
        elif f == 2:
            print("Leider wird diese Funktion noch nicht unterstützt")
        elif f == 3:
            print("Leider wird diese Funktion noch nicht unterstützt")
                
        x = input("Beenden? (j/n)")

def new_account():
    name = input("Geben Sie den Namen des Konto ein: ")
    amount = int(input("Wie viel ist auf dem Konto: "))
    interest = float(input("Wie hoch ist der Zinssatz: "))

    account = Account(name, amount, interest)
    return account
        
#Hauptprogramm
accounts = {}
run(accounts)
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Dein Schlüssel fürs dict ist überflüssig - was bringt Dir die "1" bei einem Konto? Nimm lieber eine Liste! Oder nutze einen sinnvollen Schlüssel für das dict.
...
User
Beiträge: 116
Registriert: Mittwoch 23. Dezember 2009, 20:22

Du könntest auch bei dem 1. Code mit UserInterface als Klasse mit setattr und getattr arbeiten, um Konten hinzuzufügen, bzw. anzusehen.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

... hat geschrieben:Du könntest auch bei dem 1. Code mit UserInterface als Klasse mit setattr und getattr arbeiten, um Konten hinzuzufügen, bzw. anzusehen.
Könnte er, aber das will er ganz sicher nicht tun.
Das Leben ist wie ein Tennisball.
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

... hat geschrieben:Du könntest auch bei dem 1. Code mit UserInterface als Klasse mit setattr und getattr arbeiten, um Konten hinzuzufügen, bzw. anzusehen.
Ich kann mir auch einen Backstein auf den Fuß werfen um mich von den Kopfschmerzen abzulenken.
angwedh
User
Beiträge: 20
Registriert: Dienstag 16. März 2010, 08:04

Hallo Zusammen
Vielen Dank für alles, nun funktioniert alles so wie ich es möchte, nun muss ich mir nur noch überlegen, ob ich es über eine Liste realisieren möchte, sprich ob es mir reicht mit Indices (?) zu rechnen oder ob ich mit einem Dict arbeiten will.

Hier noch kurz wie ich nun das Problem gelöst habe, ich probiere zuerst mit dict:

Code: Alles auswählen

    a = new_account()
    accounts[a.name] = a
Das mein Problem schlussendlich in die Schmerzbiologie gehen würde, hätte ich nicht gedacht;)

Gruss
angwedh
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Mal ernsthaft: Wäre der "natürliche Schlüssel" für ein dict von Konten nicht eine Kontonummer? Selbst, wenn es nur interne "Buchungskonten" sind? Nur mal so als kleiner Tipp ...
angwedh
User
Beiträge: 20
Registriert: Dienstag 16. März 2010, 08:04

Da frag ich mich doch gerade, wieso ich nicht darauf gekommen bin! Zum Glück gibt es noch nicht allzuviel umzuschreiben!
Danke für diesen Tipp
Gruss
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

/me hat geschrieben:
... hat geschrieben:Du könntest auch bei dem 1. Code mit UserInterface als Klasse mit setattr und getattr arbeiten, um Konten hinzuzufügen, bzw. anzusehen.
Ich kann mir auch einen Backstein auf den Fuß werfen um mich von den Kopfschmerzen abzulenken.
LOL... you made my day! :-D
Antworten