Frage zu Klassen und deren Aufbau

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
pengo
User
Beiträge: 15
Registriert: Dienstag 10. Oktober 2006, 22:28

Samstag 8. November 2008, 20:19

Guten Abend zusammnen,

ich bin noch neu hier :-) ich hoffe ich mach alles richtig.

Ich habe vor 2 Wochen angefangen mich mit Python zu beschäftigen. Ich habe schon
so ein paar Erfahrungen mit Perl gemacht aber das wahr auch schon ein bisschen her und bis jetzt waren es auch nicht wirklich große Programme sonder kleine Helferleins.

Da Python ja gerade ideal ist für OO hab ich versuch mich intensiver mit der ganz Materie zu beschäftigen habe erste auch das openbook verwende aber soll ja gar nicht "so dolle" sein. Dann hab ich die alternativ Tuts durch/ange -lesen leider habe jetzt ich noch ein paar Verständnis Probleme oder stehe einfach gewaltig auf dem Schlauch.

So genug Gelabber.

Ich habe mir vor genommen ein kleines Kassenprogramm zu schreiben inklusive Benutzer-, Auftragsverwaltung und Datenbank Anbindung.

Ich habe mir jetzt ein paar Gedanken zum Aufbau gemacht, leider bin ich durch das ganze lesen der verschiedenen Tutorials ein wenig verwirrt ^^.

Mich interessiert am Beispiel der Kundenverwaltung, eigentlich ganz einfach ^^,
was kommt alles in eine Klasse wie Handel ich am besten mit Setter und Getter.

Ich habe mal was zusammen getippt aber bin fest davon überzeugt das das so nicht sein kann ^^ es geht bis jetzt noch mehr um den allgemeinen Aufbau.

Dann habe ich noch die Frage, da ich ja eine Kundenverwaltung schreiben möcht
das heißt Kunden in der Datenbank speichern/löschen usw., mach ich das direkt in der Klasse Kunde oder nehme ich da ein extra Klasse Bsp. Kundenbetreuer?
oder was ganz anders?

Code: Alles auswählen

#-*- coding utf8 --

class Kunde(object):
   def __init__(self,  kundennummer,  name1,  name2="none", 
                     strassenname="none",  wohnort="none", mailadresse="none"):
      self._kundennummer = kundennummer
      self._name1 = name1
      self._name2 = name2
      self._strassenname = strassenname
      self._wohnort = wohnort
      self._mailadresse = mailadresse
      
   def set_name1(self,  name1):
      self.__name1 = name1

   def set_name2(self,  name2):
      self.__name2 = name2
   
   def set_strassenname(self,  strassenname):
      self.__strassenname = strassenname
      
   def set_wohnort(self,  wohnort):
      self.__wohnort = wohnort
   
   def set_mailadresse(self,  mailadresse):
      self.__mailadresse = mailadresse
   
   def get_kundennummer(self):
      return self.__kundennummer
   
   def get_name1(self):
      return self.__name1
   
   def get_name2(self):
      return self.__name2
   
   def get_strasse(self):
      return self.__strasse
      
   def get_wohnort(self):
      return self.__wohnort
      
   def get_mailadresse(self):
      return self.__mailadresse

Ich hoffe das die Fragen nicht allzu komisch sind!

Gruß pengo
Benutzeravatar
str1442
User
Beiträge: 520
Registriert: Samstag 31. Mai 2008, 21:13

Samstag 8. November 2008, 20:39

Setter und Getter brauchst du nur, wenn das setzen eines Wertes außer eben dieser Aktion noch andere Aktionen erfolgen lassen soll. Das heißt, hier komplett unnötig, sofern du nicht planst, diese Methoden zu erweitern. Außerden haben Methoden, die noch was anderes machen, in der Regel andere Namen als "get/set_xyz", was auch gut so ist.

Setzen kannst du Werte ansonsten in Python direkt. einfach über einen Attributszugriff auf die Variable zugreifen und damit machen, was man will.

Alternativ empfehlen sich properties, such mal im Forum nach property.

Deine Unterstriche sind übringens unnötig und falsch. _ an sich ist nur dazu da, um Dinge als klassenintern oder mit einer Warnung vor der direkten Nutzung zu versehen, aber es wird nichts erzwungen. __ ist offiziell nur dazu da, um Namenskollisionen zu vermeiden, und ist auch nicht "privat".

Du greifst plötzlich über __ auf eine _ variable zu. Das geht nicht, weil da kein Mechanismus dahinter steht. Du kannst Variablen nur über dem spezifiziertem Namem ansprechen.

Kunden kannst du direkt über eine Methode sich wo registrieren lassen, du kannst es aber auch anders händeln. Gibt zig Möglichkeiten, Stichwort "Creational Patterns".

@Openbook:

Ich habe da keine Erfahrungen mit, aber nach allem was ich gelesen habe, soll es wohl extrem grottig sein.
Zuletzt geändert von str1442 am Samstag 8. November 2008, 20:42, insgesamt 1-mal geändert.
DasIch
User
Beiträge: 2462
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Samstag 8. November 2008, 20:41

Was spricht gegen

Code: Alles auswählen

class Customer(object):
    def __init__(self, uid, forename, surname=None, street=None, location=None,
            mail_address=None):
        self.uid = uid
        self.forename = forename
        self.surname = surname
        self.street = street
        self.location = location
        self.mail_address = None
Wenn du wirklich getter und setter brauchst(bei dem Code brauchst du es nicht) schau dir mal property an. Wenn man schon New Style Classes benutzt sollte man auch deren Möglichkeiten nutzen.
BlackJack

Samstag 8. November 2008, 21:23

Und wenn das am Ende in einer Datenbank landen soll, könnte man sich auch gleich mal einen "Object Relational Mapper" (ORM) anschauen. Zum Beispiel SQLAlchemy oder SQLObject.
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Sonntag 9. November 2008, 01:17

str1442 hat geschrieben:@Openbook:

Ich habe da keine Erfahrungen mit, aber nach allem was ich gelesen habe, soll es wohl extrem grottig sein.
Naja, du siehst ja nach dem geposteten Code was für Schäden es verursacht :twisted: (nicht persönlich nehmen pengo, bei dir sehe ich dadurch dass du die Sachen kritisch siehst durchaus Potential zur Besserung)

*sigh* Es scheint tatsächlich Bedarf nach einem Buch zu geben, dass OOP in Python erklärt und zwar so wie man das richtig machen würde. :roll:
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Benutzeravatar
pengo
User
Beiträge: 15
Registriert: Dienstag 10. Oktober 2006, 22:28

Sonntag 9. November 2008, 13:26

Ich danke euch erstmal recht herzlich für eure Hilfe.
Werde mich jetzt erst mal mit euren Tipps auseinander setzen :) und ein bisschen herumprobieren und dann später noch einmal auf euch zukommen :).
@Leonidas

Naja, du siehst ja nach dem geposteten Code was für Schäden es verursacht Twisted Evil (nicht persönlich nehmen pengo, bei dir sehe ich dadurch dass du die Sachen kritisch siehst durchaus Potential zur Besserung)

*sigh* Es scheint tatsächlich Bedarf nach einem Buch zu geben, dass OOP in Python erklärt und zwar so wie man das richtig machen würde. Rolling Eyes
Ist verziehen dir ;), mir war irgend wie schon bewusst das dass was ich da gepostet habe nicht stimmen kann, hab also mit so was gerechnet ;).

Und es stimmt ich würde mich schon sehr über ein anständiges OOP Tut freuen :D!

vielen Dank Gruß pengo
Benutzeravatar
pengo
User
Beiträge: 15
Registriert: Dienstag 10. Oktober 2006, 22:28

Montag 10. November 2008, 21:01

Hallo zusammen,

ich hatte euch ja gewarnt das ich wieder kommen werde, allerdings hoffe ich das es nicht ganz so schlimm aussieht wie das letzte mal *hope*.

Ich weiß ihr habt besseres zu tun als irgend eine schlechten Code zu überprüfen.
Ich würde mich aber freuen wenn trotzdem jemand sich erbarmen würde und nur ganz kurz drüber schauen könnte nur damit ich weiß ob ich immer noch auf dem Holzweg bin oder es schon besser aussieht.

Hier einfach mal mein bisherigen Code von meiner Benutzerverwaltungs Klasse.

gebet("Bitte lasse es erträglich sein") ^^

Code: Alles auswählen

# -*- coding utf8 --

from sqlalchemy import create_engine

class AccountManager(object): 
    
    customer_data_body = ("uid", "forename", "surename",  "company", 
                            "location","call_number", "fax_number", 
                            "mail_address")
    
    def __init__(self,  database_connect_data):
        '''Connect to Customer Database '''

        if database_connect_data["engine"] == "sqlite":
            
            if "database" is not database_connect_data:
                database_connect_data["database"] = ":memory:"
        
            connect_data_string = database_connect_data["engine"] + ":///" + \
                                    database_connect_data["database"]
                                    
            engine = create_engine(connect_data_string, echo=True)
        
        else :
            database_access_data = ""
            database_host_data = ""
            database_name = ""

            if database_connect_data.has_key("user"):
                database_access_data = database_connect_data["user"]
                
                if database_connect_data.has_key("password"):
                    database_access_data += ":" + \
                                            database_connect_data["password"]
                
                database_access_data += "@"
            
            if database_connect_data.has_key("host"):
                database_host_data = database_connect_data["host"]
                
                if database_connect_data.has_key("port"):
                    database_host_data += ":" + database_connect_data["port"]
            
            if database_connect_data.has_key("database"):
                database_name = database_connect_data["database"]
            
            connect_data_string = database_connect_data["engine"] +  "://" +  \
                                    database_access_data +  "/" +  \
                                    database_host_data +  "/" +  \
                                    database_name
                              
            engine = create_engine(connect_data_string, echo=True)
        
        try: 
            self.connection = engine.connect()
        except:
            print "Connection to Database ...faild"


    
    def create_customer_data(self):
        # Fuege customer_data_body mit DB Abfragen zusammen
        pass
    
    def create_customer(self, forename, surname, company=None,  
                        street=None, location=None, call_number=None,  
                        fax_number=None,  mail_address=None):        
        # Benutzer in DB schreiben
        
        return uid
        
    def kill_customer(self,  uid):
        # Benutzer aus DB loeschen
        pass
        
    def modify_customer(self, customer_daten):
        # Benutzerangaben in DB aendern
        pass
        
    def get_customer(self,  uid):
        #Benutzer aus DB lesen und Daten bereit stellen

        return customer_daten
vielen Dank und Adios pengo
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Montag 10. November 2008, 21:05

Also ich würde die Klasse nicht in ``__init__`` irgendwelche weitreichenden aktionen machen lassen sondern lieber in einem expliziten ``connect``. Auch ist es keine gute Idee, generell alle Exceptions abzufangen und dann ggf. eine falsche Fehlermeldung auszugeben.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Benutzeravatar
pengo
User
Beiträge: 15
Registriert: Dienstag 10. Oktober 2006, 22:28

Montag 10. November 2008, 21:14

Vielen Dank für die Zeit,

@Leonidas wie kann man nur so schnell sein :-)

okey, habe dann __init__ in connect umbenannt.

Zwecks try ... except würde ich dann in dem Fall eher komplett weglassen, oder?
Benutzeravatar
str1442
User
Beiträge: 520
Registriert: Samstag 31. Mai 2008, 21:13

Montag 10. November 2008, 21:19

Die ganzen Strings in Variablen auslagern. Dieses "///" Generiere am besten auch, oder besser in eine Funktion, da es ja mehrere Arten zu geben scheint, wobei ich keine Ahnung habe, was das soll.

Du prüft mit is not auf String Identität. Bedeutet, du überprüfst, ob ein String *nicht* *der selbe* wie der referenzierte ist. Dh, du zwei Referenzen hast, die beide auf das gleiche im Speicher liegende Objekt linken. Du suchst vermutlich eher "==" und "!=" für Gleichheit (nicht Selbigkeit ;) ).

Ansonsten sieht das schon ganz gut aus.
Antworten