- Nutze alle Lernfunktionen, wie Tests, Quizze und Umfragen.
- Schreibe Beiträge und tausche dich in unseren Foren aus.
- In einigen Lernangeboten bestätigen wir dir die Teilnahme.
AI.Lab
Kursthemen
-
-
Klassen
Klassen sind ein grundlegendes Konzept in objektorientierten Programmiersprachen wie Python. Sie dienen dazu, Code zu strukturieren, indem sie Daten und die damit verbundenen Operationen in einem Paket zusammenfassen. Um eine Klasse im Programm nutzen zu können, muss diese definiert werden.
Die Definition einer Klasse in Python ist eine Anweisung, die eine Schablone oder einen Bauplan für die Erstellung von Objekten bereitstellt. Eine Klasse definiert die Datenattribute (Variablen) und Methoden (Funktionen), die jedes Objekt dieser Klasse besitzen wird.Eine Klasse ist der Oberbegriff, zum Beispiel ein Auto. Die Instanzen oder Objekte der Klasse sind dann z. B. ein BMW oder ein Twingo. Diese haben dann weitere Attribute, wie Farbe, maximale Geschwindigkeit etc. Die Klassen können so sehr komplex werden, deshalb sollte auf irrelevante Informationen verzichtet werden.
Hier ist ein Beispiel für der Syntax für die Definition einer Klasse in Python:
-
class Auto: # Klassenattribut: Ist für die Klasse definiert uns somit für alle Instanzen gleich! anzahl_autos = 0 # Konstruktor: Erstellt beim Aufruf ein neues Objekt der Klasse. Die Attribute bekommen die übergebenen Werte zugewiesen (Marke und Farbe). def __init__(self, marke, farbe="schwarz"): # Anlegen der benötigten Instanzvariablen self.marke = marke # mit self.marke wird auf das Attribut der Instanz zugegriffen (ähnlich wie this.marke in Java) und so die übergebene Marke gesetzt. self.farbe = farbe Auto.anzahl_autos += 1 # erhöhen des Klassenattributs print(f"Du hast nun {Auto.anzahl_autos} Auto(s). Es ist ein {marke} in {farbe}.") # Methode def lackieren(self, farbe): self.farbe = farbe f"Dein {self.marke} ist nun {farbe}!" # Objekt erstellen mein_auto = Auto("Toyota", "blau") # Methodenaufruf mein_auto.lackieren("rot")
-
Hier sind die wichtigen Bestandteile einer Klassendefinition:
class
: Das Schlüsselwort class leitet die Definition einer Klasse ein.
Klassenname
: Dies ist der Name der Klasse, der verwendet wird, um neue Objekte dieser Klasse zu erstellen.
Klassenattribute
: Diese sind Variablen, die allen Instanzen (Objekten) der Klasse gemeinsam sind. Sie werden innerhalb der Klasse definiert, aber außerhalb von Methoden.
Konstruktor ( __init__ )
: Dies ist eine spezielle Methode, die beim Erstellen eines neuen Objekts der Klasse aufgerufen wird. Sie initialisiert die Attribute des Objekts. Im Konstruktor können auch Standardwerte festgelegt werden, für den Fall, dass ein Argument weggelassen wird. (Siehe oben: farbe=schwarz)
Instanzvariablen
: Instanzvariablen können im Konstruktor angelegt werden. Jede Instanz der Klasse hat dann diese Variablen. Syntax:self.variable = wert
Methoden
: Dies sind Funktionen, die innerhalb der Klasse definiert sind und auf Objekten dieser Klasse aufgerufen werden können. Sie können auf die Datenattribute der Klasse zugreifen und diese verarbeiten.
self
: Wird verwendet, um auf die Instanz der Klasse zu verweisen, auf der die Methode aufgerufen wird. Dies geschieht ähnlich wie in Java mitthis
, allerdings muss in Pythonself
immer als erster Parameter einer Instanzmethode angegeben werden.Es wird keine Dynamische Speicherallokation benötigt. Objekte werden durch den Namen der Klasse und die benötigten Parameter in Klammern erzeugt (z.B. Auto("Toyota", "blau")).
-
Methodenarten
Instanzmethode
Die Instanzmethode wurde oben bereits gezeigt. Sie hat den als ersten Parameter
self
. Sie werden am häufigsten verwendet. Sie werden auf Instanzen angewendet (mein_auto
.lackieren()) und können auf Instanzvariablen zugreifen.Klassenmethoden
Klassenmethoden arbeiten mit der Klasse selbst und nicht mit Instanzen. Sie werden über den Dekorator
@classmethod
über der Funktionsdefinition gekennzeichnet und haben als ersten Parameter statt self den Parametercls
. Klassenmethoden haben übercls
direkten Zugriff auf die Klassenattribute, können dafür aber nicht auf Instanzvariablen zugreifen.Statische Methoden
Statische Methoden arbeiten auf Klassenebene und haben weder auf Klassen- noch auf Instanzvariablen direkten Zugriff. Gekennzeichnet werden sie durch den
@staticmethod
Dekorator. Sie werden in der Regel als Hilfsfunktionen genutzt, die nicht direkt mit Instanz- oder Klassenattributen arbeiten müssen.Hier folgt eine Beispielklasse mit allen drei Funktionsarten und ihren Aufrufen:
-
class Begrüßung: standart = "Nutzer" @staticmethod def informal(): return "Hi!" @classmethod def formal(cls): return f"Guten Tag {cls.standart}!" def __init__(self, name): self.name = name def persönlich(self): return f"Hallo, {self.name}!" # Aufrufe der verschiedenen Methoden print(Begrüßung.informal()) # Statische Methode: Aufruf über Klasse print(Begrüßung.formal()) # Klassenmethode : Aufruf über Klasse begrüßung = Begrüßung("name") # Erstellung einer Instanz print(begrüßung.persönlich()) # Instanzmethode: Aufruf über Instanz
-
Übung (Bankkonto)
Erstelle eine Python-Klasse namens Konto, die ein Bankkonto repräsentiert. Das Konto soll folgende Funktionalitäten haben:
Ein
Konstruktor
, der die folgenden Parameter akzeptiert:
kontonummer
: Die Kontonummer des Kontos.
inhaber
: Der Name des Kontoinhabers.
saldo
: Der anfängliche Saldo des Kontos. Wenn kein Saldo angegeben wird, soll der Standardwert 0 sein.Eine Methode namens
einzahlen
, die einen Betrag als Parameter akzeptiert und den Betrag zum aktuellen Saldo des Kontos hinzufügt.
Eine Methode namensabheben
, die einen Betrag als Parameter akzeptiert und den Betrag vom aktuellen Saldo des Kontos abzieht. Stellen Sie sicher, dass das Konto ausreichend Geld hat, bevor Sie einen Betrag abheben.
Eine Methode namenssaldo_abfragen
, die den aktuellen Saldo des Kontos zurückgibt.
Implementieren Sie die KlasseKonto
gemäß den obigen Anforderungen und testen Sie sie, indem Sie ein Konto erstellen, Geld einzahlen, Geld abheben und den aktuellen Saldo abfragen.Bonusaufgabe (optional): Fügen Sie der Klasse Konto eine Methode hinzu, die es dem Benutzer ermöglicht, den Kontoinhaber zu ändern.
-
Übung (Bankkonto)
Erstelle eine Python-Klasse namens Konto, die ein Bankkonto repräsentiert. Das Konto soll folgende Funktionalitäten haben:
Ein
Konstruktor
, der die folgenden Parameter akzeptiert:
kontonummer
: Die Kontonummer des Kontos.
inhaber
: Der Name des Kontoinhabers.
saldo
: Der anfängliche Saldo des Kontos. Wenn kein Saldo angegeben wird, soll der Standardwert 0 sein.Eine Methode namens
einzahlen
, die einen Betrag als Parameter akzeptiert und den Betrag zum aktuellen Saldo des Kontos hinzufügt.
Eine Methode namensabheben
, die einen Betrag als Parameter akzeptiert und den Betrag vom aktuellen Saldo des Kontos abzieht. Stellen Sie sicher, dass das Konto ausreichend Geld hat, bevor Sie einen Betrag abheben.
Eine Methode namenssaldo_abfragen
, die den aktuellen Saldo des Kontos zurückgibt.
Implementieren Sie die KlasseKonto
gemäß den obigen Anforderungen und testen Sie sie, indem Sie ein Konto erstellen, Geld einzahlen, Geld abheben und den aktuellen Saldo abfragen.Bonusaufgabe (optional): Fügen Sie der Klasse Konto eine Methode hinzu, die es dem Benutzer ermöglicht, den Kontoinhaber zu ändern.
-
Übung (Bankkonto) Teil 2
Da es doch ganz schön unsicher ist, dass jeder einfach Geld aufladen und abheben kann, wollen wir nun noch einen Pincode zum Konto hinzufügen. Dieser soll vor Ausführung der Methoden abgefragt werden. Füge den Pincode dazu zum Konstruktor hinzu und passe die Methoden an, sodass diese nur mit richtigem Code funktionieren.
-
Übung Bankkonto Teil 3
Bisher haben wir nur mit einem einzigen Konto gearbeitet. Nun wollen wir aber die Funktionalität von Klassen ausnutzen. Erstelle eine weitere Instanz der Klasse. Implementiere zudem eine Methode
ueberweisen
, mit der du Geld von einem zum anderen Konto schicken kannst. Überprüfe danach die Funktion danach selbst.Denke daran, deinen Code zu kommentieren, sodass du ihn auch später noch verstehst. Zudem fallen dabei oft noch kleine Fehler auf!
-
Wichtige Methoden
Es gibt einige Methoden, wie z. B. den Konstruktor oder die
__repr__
Methode (gibt eine textuelle Darstellung der Instanz zurück), die für jede Klasse vordefiniert sind. Diese können wir überschreiben, uns so für unsere Zwecke anpassen. Es folgen die wichtigsten vordefinierten Funktionen:__init__(self,...)
: Eine Initialisierungsmethode, die die Attribute der Klasse initialisiert. Die übergebenen Parameter entsprechen den Attributen der Klasse.
__repr__(self)
: Eine Repräsentationsmethode, die eine textuelle, detaillierte Darstellung des Objekts für Entwickler zurückgibt.
__eq__(self, other)
: Eine Gleichheitsmethode, die definiert, wie zwei Objekte miteinander verglichen werden. Sie überprüft, ob die Attribute der beiden Objekte gleich sind. Bezogen auf das obige Beispiel könnten z. B. Kontonummer oder Kontoinhaber verglichen werden, um festzustellen, ob die Konten gleich sind. Die Gleichheit wird also durch den Programmierer festgelegt.
__str__(self)
: Eine Zeichenfolgen-Methode, die eine benutzerfreundliche Zeichenfolgen-Darstellung des Objekts zurückgibt. Diese Methode wird aufgerufen, wennstr()
auf das Objekt angewendet wird oder ein Objekt in der Konsole ausgegeben wird.Hier sind ein paar Beispiele dafür:
-
class Student: def __init__(self, name, vorname, klasse, notendurchschnitt): self.name = name self.vorname = vorname self.klasse = klasse self.notendurchschnitt = notendurchschnitt def __str__(self): return f"{self.vorname} {self.name} ist in der {self.klasse} Klasse und hat einen Notendurchschnitt von {self.notendurchschnitt}." def __eq__(self,other): return self.name==other.name and self.vorname==other.vorname stu1 = Student("Mustermann", "Max", 7, 1.3) stu2 = Student("Mustermann", "Marina", 9, 2.9) stu3 = Student("Mustermann", "Max", 12, 4.0) print("Standartausgaben:\n", stu1) print(str(stu2)) print(stu1 == stu2) # Beim Vergleich von zwei Instanzen der Klasse wird automatisch die definierte Vergleichsoperation verwendet print(stu1.__eq__(stu3)) # Alternativ kann diese auch so aufgerufen werden. print(Student.__eq__(stu2,stu3)) # oder über die Klasse (dann müssen 2 Argumente übergeben werden) print("Technische Ausgabe: ", repr(stu1))
-
Verschachtelung
Klassen können auch ineinander verschachtelt werden. Das heißt, dass eine Klasse Instanzen einer anderen Klasse beinhalten kann. Betrachten wir zum Beispiel unsere Auto Klase von oben, so können wir eine Klasse
Fuhrpark
hinzufügen, welche alle Autos eines Besitzers beinhaltet. -
class Auto: # Konstruktor: Erstellt beim Aufruf ein neues Objekt der Klasse. Die Attribute bekommen die übergebenen Werte zugewiesen (Marke und Farbe). def __init__(self, marke, farbe="schwarz"): # Anlegen der benötigten Instanzvariablen self.marke = marke self.farbe = farbe # Methode def lackieren(self, farbe): self.farbe = farbe f"Dein {self.marke} ist nun {farbe}!" def __eq__(self, other): # Festlegen des Verlgeichs zwischen den Autos. Standartmäßig werden die Objekte verglichen, wir vergleichen nur Farbe und Marke return self.marke == other.marke and self.farbe == other.farbe def __str__(self): return f"{self.marke} in {self.farbe}" class Fuhrpark: def __init__(self): self.autos = [] # Erstellung einer leeren Liste für Autos def auto_hinzufuegen(self, auto): self.autos.append(auto) # Hinzüfgen von Autos def auto_entfernen(self, auto): if auto in self.autos: # Wenn Auto mit gleicher Farbe und Marke in der Liste -> Entferne es self.autos.remove(auto) def __str__(self): str = "Mein Fuhrpark besteht aus:\n" for auto in self.autos: str += f"{auto}, " return str[:-2] # ", " aus String entfernen und zurückgeben # Auto Instanzen ersetllen bmw = Auto("bmw","rot") mercedes = Auto("mercedes","blau") bmw2 = Auto("bmw","rot") # Neuen Fuhrpark erstellen fuhrpark = Fuhrpark() # Autos hinzufügen fuhrpark.auto_hinzufuegen(bmw) fuhrpark.auto_hinzufuegen(bmw2) fuhrpark.auto_hinzufuegen(mercedes) # Fuhrpark ausgeben print(fuhrpark) # Autos aus Fuhrpark entfernen fuhrpark.auto_entfernen(bmw) fuhrpark.auto_entfernen(bmw) print(fuhrpark)
-
Datenklassen
Datenklassen sind eine Erweiterung des Klassenkonzepts in Python und bieten eine vereinfachte Möglichkeit, Datencontainer zu definieren. Sie ermöglichen eine elegante und übersichtliche Implementierung von Klassen, indem sie grundlegende Funktionalitäten wie
__init__
,__repr__
,__eq__
und__str__
automatisch generiert, was Zeit spart und Fehler vermeidet. Sollte für diese eine andere Implementierung gewünscht sein, können sie einzeln definiert und damit überschrieben werden.Ein weiterer Vorteil von Datenklassen ist die Möglichkeit, unveränderliche Datencontainer zu erstellen. Durch Festlegen des Parameters
frozen=True
im Dekorator wird die Datenklassen unveränderlich gemacht, was bedeutet, dass ihre Attribute nach der Initialisierung nicht geändert werden können.Da die Verwendung von Datenklassen ansonsten mit der von normalen Klassen übereinstimmt, folgen nun zwei Beispiele für die Erstellung von Datenklassen.
-
from dataclasses import dataclass # Deklaration einer Dataclass mit dem Dekorator @dataclass @dataclass class Person: # Hier werden jetzt alles Instanzvariablen festgelegt die die Klasse haben soll. name: str # Attribut für den Namen der Person alter: int # Attribut für das Alter der Person stadt: str # Attribut für die Stadt, in der die Person lebt # Hier können verschiedene Methoden für die Klasse erstellt werden. def geburtstagsfeier(self): self.alter += 1 # Erhöht das Alter der Person um 1 print(f"Alles Gute zum Geburtstag, {self.name}!") def umzug(self, neue_Stadt): self.stadt = neue_Stadt person1 = Person("Dirk", 25, "Hamburg") # Gibt die vordefinierte Methode __str__ aus: print(person1)
-
from dataclasses import dataclass @dataclass(frozen=True) # Der Zusatz (frozen = True) sorgt dafür, dass die Klasse nach der Erstellung nicht mehr verändert werden kann. class Rechteck: breite: float hoehe: float = 3 # Auch hier können Standartwerte festgelegt werden, sodass diese im Konstruktor weggelassen werden können. def flaeche(self): return self.breite * self.hoehe # Beispielanwendung rechteck = Rechteck(5.0, 3.0) print("Fläche:", rechteck.flaeche()) # Versuch, die Breite des Rechtecks zu ändern # rechteck.width = 7.0 # Das würde eine AttributeError auslösen, da die Dataclass unveränderlich ist
-