Informatik Sek II
Objektorientiertes Programmieren

Python
LFB.-Kurs
W. Arnhold
[ Übersicht | vorige Seite | nächste Seite | Ganz unten ]
Python Python - Syntax :  Klassen  II

Klassen  II

Welchen Vorteil hat es nun, den Stack in eine Klasse zu verpacken? Man hätte die Liste doch auch so definieren können und die Prozeduren ebenfalls.

Natürlich hätte man. Dabei hätte man sogar noch die Möglichkeit gehabt, den Stack durchzugehen, ohne die Objekte zu löschen. Schließlich wird in dem Schreibtisch-Beispiel die Arbeit bereits durch das Aufzählen erledigt.

Das ist sicher richtig. Aber ein Datenobjekt, mit dem dies alles möglich ist, ist eben eine Liste und kein Stack. Der Stack wird genau in dieser Beschränkung gebraucht. Wer einen Stack haben will, der will sicher sein, dass nach einem "pop" das oberste Element entfernt ist. Wer etwas anderes will, braucht keinen Stack.

Eine Klasse kann also von einem Objekt der Wirklichkeit (ist ein Stack wirklich?) genauer als mit anderen Methoden dessen Eigenschaften nachbauen. Sie kann unter anderem auf diese Art auch ein höheres Maß an Sicherheit liefern. Ein Beispiel:
die Klasse "Zensurenpunkte" definiert eine Zensurenpunktezahl der Gesamtschule im Bereich 0 - 15, dabei ist "p" ist die Punktezahl, Punkte dürfen nur ganze Zahlen sein:

import sys
import types

class Zensurenpunkte:
        def __init__(self, p):
                if type(p) != types.IntType:
                        print 'Ungültiger Parameter für Zensurenpunkte:',
                        print p
                        sys.exit(-1)        # Programmabbruch
                if not 0 <= p <= 15:
                        print 'Ungültige Punktezahl: %d' % p
                        sys.exit(-1)        # Programmabbruch
                self.punkte = p 
Mit diesen Prüfungen beim Konstruktor ist sichergestellt, dass eine Instanz der Klasse Zensurenpunkte entweder korrekt ist oder gar nicht ist. Und das ist doch schon was!

Nun ist der Wert drin. Wie kommt er aber wieder raus?

        def wert(self):
                return self.punkte
So!

Wir wollen mal versuchen, von dieser Klasse Gebrauch zu machen. Testen Sie ruhig mal die eingebaute Knautschzone der Klasse "Zensurenpunkte" aus!

from klassen1 import Stack
zensurenliste = Stack()

print 'Von der nun folgenden Import-Anweisung stammt die Schreibtisch-'
print 'frage. Sie wird hier noch mal aufgerufen. Einfach "ende" eingeben.'
print
print 'Bitte die Punkte eingeben (oder "ende")!'
while 1:
        eingabe = raw_input()
        if not eingabe:
                continue
        if eingabe == 'ende':
                break
        intpunkte = eval(eingabe)
        punkte = Zensurenpunkte(intpunkte)
        zensurenliste.push(punkte)
Da wir über die Tastatur nur Zeichenketten eingeben können, müssen diese mit "eval" noch in Zahlen gewandelt werden.
Hier sehen wir den Gebrauch eines Konstruktors, der den Dateninhalt der Klasse sofort beim Aufruf bekommt.
Der Verweis auf die Instanz von "Zensurenpunkte", der in "punkte" lag, wird auf dem Stack gespeichert. Beim nächsten Schleifendurchlauf wird in der darüberliegenden Zeile erneut der Konstruktor aufgerufen und eine neue Instanz erzeugt, deren Verweis dann auch auf dem Stack landet.
print 'Folgende Punktzahlen wurden eingegeben:'
while not zensurenliste.empty():
        print '%d Punkte' % zensurenliste.pop().wert()
Na, das sieht aber wieder mal sehr trickreich aus! Muss denn das sein? Nein. Man hätte auch schreiben können:
        p = zensurenliste.pop()
        print '%d Punkte' % p.wert()
p ist eine Instanz vom Typ "Zensurenpunkte" und hat also eine Klassenprozedur "wert".

Inhaltlich ist beides gleich, nur dass im ersten Fall die Erzeugung der Variablen "p" zum Zwischenspeichern des Verweises entfällt. Welche Methode gefällt ihnen besser?


[ Übersicht | vorige Seite | nächste Seite | Ganz oben ]

©   W. Arnhold Oktober 2000