5. Klassen und Objekte
Die Klasse ist die Vorlage, nach der Objekte erstellt werden. Man sagt, dass ein Objekt eine Instanz einer Klasse ist.
![]() |
5.1. Eine Objektklasse
Programm (classes_01)
# -*- coding=utf-8 -*-
class Objet:
"""une classe Objet vide"""
# Jede Variable kann per Definition Attribute haben
obj1=Objet()
obj1.attr1="un"
obj1.attr2=100
# zeigt das Objekt an
print "objet1=[{0},{1}]".format(obj1.attr1,obj1.attr2)
# ändert das Objekt
obj1.attr2+=100
# Zeigt das Objekt an
print "objet1=[{0},{1}]".format(obj1.attr1,obj1.attr2)
# weist die Referenz „objekt1“ dem Objekt „objekt2“ zu
obj2=obj1
# ändert „Obj2“
obj2.attr2=0
# zeigt beide Objekte an
print "objet1=[{0},{1}]".format(obj1.attr1,obj1.attr2)
print "objet2=[{0},{1}]".format(obj2.attr1,obj2.attr2)
Anmerkungen:
- Zeile 4: eine weitere Form des Kommentars. Dieser, dem drei „ vorangestellt sind, kann sich über mehrere Zeilen erstrecken;
- Zeilen 3–4: eine leere Objektklasse;
- Zeile 7: Instanziierung der Klasse Objet;
- Zeile 17: Kopieren von Referenzen. Die Variablen obj1 und obj2 sind zwei Zeiger (Referenzen) auf dasselbe Objekt.
Ergebnisse
5.2. Eine Klasse „Person“
Programm (classes_02)
# -*- coding=utf-8 -*-
class Personne:
# Attribute der Klasse
# nicht deklariert – können dynamisch angelegt werden
# Methode
def identite(self):
# verwendet a priori nicht vorhandene Attribute
return "[{0},{1},{2}]".format(self.prenom,self.nom,self.age)
# ---------------------------------- main
# Die Attribute sind öffentlich und können dynamisch erstellt werden
p=Personne()
p.prenom="Paul"
p.nom="Langevin"
p.age=48
# Aufruf einer Methode
print "personne={0}\n".format(p.identite())
Anmerkungen:
- Zeilen 3–10: eine Klasse mit einer Methode;
- Zeile 8: Jede Methode einer Klasse muss als ersten Parameter das Objekt self haben, das das aktuelle Objekt bezeichnet.
Ergebnisse
5.3. Die Klasse „Person“ mit einem Konstruktor
Programm (classes_03)
# -*- coding=utf-8 -*-
class Personne:
# Konstruktor
def __init__(self,prenom,nom,age):
self.prenom=prenom;
self.nom=nom;
self.age=age;
# Methode
def identite(self):
# verwendet a priori nicht vorhandene Attribute
return "[{0},{1},{2}]".format(self.prenom,self.nom,self.age)
# ---------------------------------- main
# ein Objekt vom Typ „Person“
p=Personne("Paul","Langevin",48)
# Aufruf einer Methode
print "personne={0}\n".format(p.identite())
Anmerkungen:
- Zeile 6: Der Konstruktor einer Klasse heißt __init__. Wie bei den anderen Methoden ist sein erster Parameter „self“;
- Zeile 18: Ein Objekt Personne wird mit dem Konstruktor der Klasse erstellt.
Ergebnisse
5.4. Die Klasse „Person“ mit Gültigkeitsprüfungen im Konstruktor
Programm (classes_04)
# -*- coding=utf-8 -*-
import re
# -------------------
# eine benutzerdefinierte Ausnahmeklasse
class MyError(Exception):
pass
class Personne:
# Konstruktor
def __init__(self,prenom="x",nom="x",age=0):
# Der Vorname darf nicht leer sein
match=re.match(r"^\s*(\S+)\s*$",prenom)
if not match:
raise MyError("Le prenom ne peut etre vide")
else:
self.prenom=match.groups()[0]
# Der Nachname darf nicht leer sein
match=re.match(r"^\s*(\S+)\s*$",nom)
if not match:
raise MyError("Le nom ne peut etre vide")
else:
self.nom=match.groups()[0]
# Das Alter muss gültig sein
match=re.match(r"^\s*(\d+)\s*$",str(age))
if not match:
raise MyError("l'age doit etre un entier positif")
else:
self.age=match.groups()[0]
def __str__(self):
return "[{0},{1},{2}]".format(self.prenom,self.nom,self.age)
# ---------------------------------- Hand
# ein Objekt vom Typ „Person“
try:
p=Personne(" Paul "," Langevin ",48)
print "personne={0}".format(p)
except MyError, erreur:
print erreur
# ein weiteres Objekt „Person“
try:
p=Personne(" xx "," yy "," zz")
print "personne={0}".format(p)
except MyError, erreur:
print erreur
# eine weitere Person
try:
p=Personne()
print "personne={0}".format(p)
except MyError, erreur:
print erreur
Anmerkungen:
- Zeilen 7–8: Eine Klasse MyError, die von der Klasse Exception abgeleitet ist. Sie fügt dieser keine neuen Funktionen hinzu. Sie dient lediglich dazu, eine benutzerdefinierte Ausnahme zu definieren;
- Zeile 13: Der Konstruktor verfügt über Standardwerte für seine Parameter. Somit entspricht die Operation p=Personne() der Formel p=Personne("x","x",0);
- Zeilen 15–9: Der Parameter prenom wird analysiert. Er darf nicht leer sein. Ist dies nicht der Fall, wird die Ausnahme MyError mit einer Fehlermeldung ausgelöst;
- Zeilen 21–25: Gleiches gilt für den Namen;
- Zeilen 27–31: Überprüfung des Alters;
- Zeilen 33–34: Die Funktion __str__ ersetzt die Methode, die zuvor identite hieß;
- Zeilen 38–42: Instanziierung einer Person und anschließende Anzeige ihrer Identität;
- Zeile 39: Instanziierung;
- Zeile 40: Anzeige. Der Vorgang fordert an, die Person p in Form einer Zeichenkette anzuzeigen. Der Python-Interpreter ruft dann automatisch die Methode p.__str__() auf, sofern diese existiert. Diese Methode erfüllt dieselbe Funktion wie die Methode toString() in Java oder in den Sprachen .NET;
- Zeilen 41–42: Behandlung einer möglichen Ausnahme vom Typ MyError. Zeigt dann die mit der Ausnahme verbundene Fehlermeldung an;
- Zeilen 44–48: Gleiches gilt für eine zweite Person, die mit falschen Parametern instanziiert wurde;
- Zeilen 50–54: Gleiches gilt für eine dritte Instanz, die mit den Standardparametern instanziiert wurde.
Ergebnisse
5.5. Hinzufügen einer Methode, die als zweiter Konstruktor dient
Programm (classes_05)
# -*- coding=utf-8 -*-
import re
# -------------------
# eine eigene Ausnahmeklasse
class MyError(Exception):
pass
class Personne:
# Attribute der Klasse
# nicht deklariert – können dynamisch erstellt werden
# Konstruktor
def __init__(self,prenom="x",nom="x",age=0):
# Der Vorname darf nicht leer sein
match=re.match(r"^\s*(\S+)\s*$",prenom)
if not match:
raise MyError("Le prenom ne peut etre vide")
else:
self.prenom=match.groups()[0]
# Der Nachname darf nicht leer sein
match=re.match(r"^\s*(\S+)\s*$",nom)
if not match:
raise MyError("Le nom ne peut etre vide")
else:
self.nom=match.groups()[0]
# Das Alter muss gültig sein
match=re.match(r"^\s*(\d+)\s*$",str(age))
if not match:
raise MyError("l'age doit etre un entier positif")
else:
self.age=match.groups()[0]
def initWithPersonne(self,p):
# initialisiert das aktuelle Objekt mit einer Person p
self.__init__(p.prenom,p.nom,p.age)
def __str__(self):
return "[{0},{1},{2}]".format(self.prenom,self.nom,self.age)
# ---------------------------------- main
# ein Objekt vom Typ „Person“
try:
p0=Personne(" Paul "," Langevin ",48)
print "personne={0}".format(p0)
except MyError, erreur:
print erreur
# ein weiteres Objekt „Person“
try:
p1=Personne(" xx "," yy "," zz")
print "personne={0}".format(p1)
except MyError, erreur:
print erreur
# eine weitere Person
p2=Personne()
try:
p2.initWithPersonne(p0)
print "personne={0}".format(p2)
except MyError, erreur:
print erreur
Anmerkungen:
- Der Unterschied zum vorherigen Skript liegt in den Zeilen 35–37. Die Methode initWithPersonne wurde hinzugefügt. Diese ruft den Konstruktor __init__ auf. Es gibt keine Möglichkeit, wie in typisierten Sprachen Methoden mit demselben Namen zu haben, die sich durch die Art ihrer Parameter oder ihres Ergebnisses unterscheiden. Es ist daher nicht möglich, mehrere Konstruktoren zu haben, die das Objekt anhand unterschiedlicher Parameter erstellen würden, in diesem Fall ein Objekt vom Typ Personne.
Ergebnisse
5.6. Eine Liste von „Person“-Objekten
Programm (classes_06)
# -*- coding=utf-8 -*-
class Personne:
...
# ---------------------------------- main
# Erstellung einer Liste von Personenobjekten
groupe=[Personne("Paul","Langevin",48), Personne("Sylvie","Lefur",70)]
# Identität dieser Personen
for i in range(len(groupe)):
print "groupe[{0}]={1}".format(i,groupe[i])
Anmerkungen:
- Zeilen 3–5: die bereits beschriebene Klasse Personne
Ergebnisse
5.7. Erstellung einer von der Klasse „Person“ abgeleiteten Klasse
Programm (classes_07)
# -*- coding=utf-8 -*-
import re
class Personne:
...
class Enseignant(Personne):
def __init__(self,prenom="x",nom="x",age=0,discipline="x"):
Personne.__init__(self,prenom,nom,age)
self.discipline=discipline
def __str__(self):
return "[{0},{1},{2},{3}]".format(self.prenom,self.nom,self.age,self.discipline)
# ---------------------------------- Hand
# Erstellung einer Liste von Personenobjekten und abgeleiteten Objekten
groupe=[Enseignant("Paul","Langevin",48,"anglais"), Personne("Sylvie","Lefur",70)]
# Identität dieser Personen
for i in range(len(groupe)):
print "groupe[{0}]={1}".format(i,groupe[i])
Anmerkungen:
- Zeilen 5–6: Die bereits definierte Klasse „Personne“;
- Zeile 8: Deklariert die Klasse „Enseignant“ als abgeleitete Klasse der Klasse „Person“;
- Zeile 10: Der Konstruktor der abgeleiteten Klasse Enseignant muss den Konstruktor der übergeordneten Klasse Personne aufrufen;
- Zeilen 21–22: Um „groupe[i]“ anzuzeigen, verwendet der Interpreter die Methode „groupe[i].__str__()“. Die verwendete Methode __str__() ist die der tatsächlichen Klasse „groupe[i]“, wie die folgenden Ergebnisse zeigen.
Ergebnisse
5.8. Erstellung einer zweiten Klasse, die von der Klasse „Person“ abgeleitet ist
Programm (classes_08)
# -*- coding=utf-8 -*-
import re
class Personne:
...
class Enseignant(Personne):
...
class Etudiant(Personne):
def __init__(self,prenom="x",nom="x",age=0,formation="x"):
Personne.__init__(self,prenom,nom,age)
self.formation=formation
def __str__(self):
return "[{0},{1},{2},{3}]".format(self.prenom,self.nom,self.age,self.formation)
# ---------------------------------- Hauptseite
# Erstellung einer Liste von Objekten vom Typ „Person“ und abgeleiteten Objekten
groupe=[Enseignant("Paul","Langevin",48,"anglais"), Personne("Sylvie","Lefur",70), Etudiant("Steve","Boer",22,"iup2 qualite")]
# Identität dieser Personen
for i in range(len(groupe)):
print "groupe[{0}]={1}".format(i,groupe[i])
Anmerkungen:
- Dieses Skript entspricht dem vorherigen.
Ergebnisse
