next up previous contents index 6163656769
Next: 5.1 Attribute, Methoden, Instanzen, Up: Programming Python Teil I: Previous: 4.6 lambda-Ausdrücke   Contents   Index


5. Klassen

Zu diesem Kapitel siehe Abbildung [*].

In diesem Abschnitt geben wir die Schreibweise mit dem Pythonprompt auf und setzen voraus, dass bereits Module geschrieben werden, die aber erst im folgenden Kapitel beschrieben werden, da dies in den Aufbau der Sprache besser passt. Dennoch können Sie im Vorgriff das kurze Kapitel über Module lesen.

Eine Klasse ist nun lediglich nichts anderes mehr als die Möglichkeit, einen neuen Objekttyp bereitzustellen, bei dem die zu bearbeitenden Datenobjekte mit den »richtigen« Funktionen gekoppelt werden. Ohne die Arbeit mit Klassen gibt es zwischen den Objekten ein heilloses Durcheinander! Wir werden nun unser feld von jetzt an als eine solche Klasse einführen und alles was wir bisher geschrieben haben, entsprechend umsetzen.

Zunächst wird mit dem Schlüsselwort class der Name der Klasse festgelegt und dem Klassenobjekt zugewiesen. Da wir später unser Objekt wieder feld nennen wollen, darf die Klasse selbst nicht feld heissen, denn dieser Klassenname steht ja sozusagen für einen Objekttyp. Setzen wir also an:

class kfeld:
Gut. Dann könnte man den Datensatz aus den ganzen Nullen einsetzen, der später bereitgestellt werden soll. Anstelle den Datensatz [[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]] jetzt einfach hinzuschreiben und ihn mit einem Namen zu versehen, gehen wir einen sehr viel besseren Weg. Wir erinnern uns daran, dass eine Namenszuweisung zu einem Datenobjekt mit dem Operator = erfolgt, eine entsprechende Zuweisung für eine Funktion dagegen mit dem Operator def. Wenn wir den Operator = nun auch als Zuweisung für unsere gerade im Aufbau befindlichen neuen Hybridobjekte gut funktionieren soll, muss er sozusagen in seiner Wirkungsweise überschrieben werden5.1.

Dieses Überschreiben erfolgt mit einer Funktion5.2, oder Methode, wie wir in Zukunft sagen werden, die den Namen __init__ tragen muss. Der Name wird mit zwei Unterstrichen begonnen und endet auch mit zwei Unterstrichen.

Es gibt nun noch eine letzte Sache zu beachten. Wenn wir später das Objekt feld vom Typ kfeld generieren wollen, so soll es den Datensatz data, der die schon bekannte verschachtelte Liste enthält, sowie alle bisher beschriebenen Funktionen input, output und start zur Verfügung stellen. Es soll natürlich aber auch möglich sein, noch weitere Objekte vom Type kfeld zu generieren, die ihr eigenes Innenleben haben. Daher wird sich im allgemeinen die Funktion feld.output() im Ergebnis von der Funktion sfeld.output() unterscheiden, wenn sfeld ein zweites kfeld-Objekt ist, das sein Eigenleben führt. Daher muss der Name des Objektes irgendwo im Objekt selbst gespeichert werden, damit keine Verwechselungen möglich sind. Jener Name, der innerhalb des Klassenobjektes auf den eigentlichen Namen des Klassenobjektes zeigt, heisst self.

Langer Rede kurzer Sinn, hier ist der Code:

class kfeld:

  #Erstellt ein 4x4 Spielfeld

  

  def __init__ (self):

    self.data[[0,0,0,0],[0,0,0,0],0,0,0,0],[0,0,0,0]]

  

  def start(self):

   for i in range(4):

    for j in range(4):

      self.data[i][j]=0

  

  def input(self,a,b,c,d)

    #Weist jeder Zeile die Werte a,b,c,d in dieser Reihenfolge zu.

    #Gibt die mit dem Zeilenindex multiplizierten Summen 

    #der letzten beiden Zeilen zurück

   

     suma=sumb=0

     for i in range (4):

       self.data[i]=[a,b,c,d]

       if i==2:

        for j in range(4):

          suma=suma+i*self.data[i][j]

       elif i==3:

        for j in range(4):

          sumb=sumb+i*self.data[i][j]

     return (suma,sumb) 

  

  def output(self):

     for in in range[i]:

       print self.data[i]

     print '\n'

Es ist sehr wichtig, dass jede Funktion an der ersten Stelle den Parameter self enthält. Nun können wir nach Belieben Objekte vom Typ kfeld einrichten. Zum Beispiel richten wir mit

feld=kfeld()
ein solches Objekt ein, dass unser gutes altes feld ist. Wir können aber auch ein zweites Objekt dieser Art einrichten, das zum Beispiel sfeld heissen soll. Die Anweisung dafür lautet jetzt

sfeld=kfeld()
Bei diesen Aufrufen wird jeweils ein eigenes Objekt eingerichtet (eine sogenannte Instanz gebildet), das über den »Konstruktor« __init__ erfolgt und ausserdem auch noch den jeweiligen Objektnamen dem Parameter self zuordnet. Beim Objekt feld zeigt der Parameter self also auf den Namen feld, beim anderen Objekt ist es der Name sfeld. Da jedes Objekt sein eigenes self besitzt, kann es dabei nicht zu Zweideutigkeiten kommen.

Der Aufruf der input-Methode erfolgt jetzt über

feld.input(1,2,3,4)
Der Name des Objektes wird also durch den »Selektor« eindeutig auf die richtige Funktion input bezogen, die eben zu feld gehört. Natürlich lautet der Code bei dem Objekt sfeld genauso. Aber es gibt selbstverständlich ganz andere Möglichkeiten, sich Klassen zusammenzubauen als es in kfeld geschehen ist. Und in diesen Klassen könnte ebenfalls eine Funktion mit dem Namen input existieren, die ganz anders arbeitet und womöglich auf den kfeld Objekten gar nicht funktioniert.

Mit

sfeld.input(2,2,2,2)
wird das Objekt sfeld auf eine ganz andere Weise verändert als feld. Folglich liefern feld.output() und sfeld.output() verschiedene Ergebnisse.



Subsections
next up previous contents index 6163656769
Next: 5.1 Attribute, Methoden, Instanzen, Up: Programming Python Teil I: Previous: 4.6 lambda-Ausdrücke   Contents   Index
Heiko Schroeder 2003-03-19