OOP - Einführungen

Es gibt in der Informatik verschiedene Programmierparadigma. Eine Variante wird als objektorientierte Programmierung bezeichnet.

Objektorientierte Programmierung erleichtert oft die Abstraktion.

Klassen und Instanzen

Ein Klasse wird oft als Bauplan einer Instanz beschrieben. In Python sehen minimale Klassendefinition wie folgt aus:

class Dog:
    pass
class Cat:
    pass

Mit inspect.isclass() können wir überprüfen ob es sich um eine Klasse handelt.

import inspect
inspect.isclass(Dog)
True
inspect.isclass(Dog)
True

Eine Instanz ist ein konkretes Exemplar das gemäß dem Bauplan einer Klasse erzeugt wurde. In Python kann eine Instanz wie folgt erzeugt werden:

my_dog = Dog()

Mit der Funktion isinstance() kann man untersuchen ob eine Instanz zu einer bestimmten Klasse gehört.

isinstance(my_dog,Dog)
True
isinstance(my_dog,Cat)
False

Wie wir sehen können ist my_dog eine Instanz von der Klasse Dog aber nicht von der Klasse Cat.

Instanzmethoden und Daten

Als nächstes wollen wir Instanz-Methoden hinzufügen. Methoden sind Funktionen

def method(self, parameters):
    statements

definiert innerhalb einer Klasse. Wichtig ist, dass der erste Parameter self lautet.

class Dog1:
    # instance methode
    def speak(self, sound):
        return f"Dog says {sound}!"

Bemerkung

Top 10 weibliche Hundenamen

Luna, Emma, Bella, Nala, Lola, Lilly, Amy, Mila, Maya, Paula

Top 10 männliche Hundenamen Charlie, Lucky, Leo, Max, Balu, Rocky, Buddy, Sammy, Bruno, Jack

Mit der Anweisung instance = Class() können wir wieder eine Instanz erzeugen.

my_dog = Dog1()

Diese Instanz können wir nun der Instanz-Methode übergeben.

Dog1.speak(my_dog,'Woof')
'Dog says Woof!'

Diese Syntax sieht nun aber nicht modern aus. Python erlaubt uns eine alternative Anweisung instance.method() welche deutlich einfacher zu lesen ist.

my_dog.speak('Woof')
'Dog says Woof!'

Diese Anweisung ist nun der Standard um Instanz-Methoden aufzurufen.

Wir wollen der Klasse nun Instanzdaten-Attribute hinzufügen um Daten speichern zu können. Python bietet hier die __init__ Methode an. Diese wird Methode wird also unmittelbar nach der Konstruktion einer Instanz aufgerufen und für eine Initialisierung genutzt.

class Dog2:
    # instance methode, __init__
    def __init__(self, name, age):
        self.name =  name # instance data attribute
        self.age = age # instance data attribute
        
    # instance methode
    def speak(self, sound):
        return f"{self.name} says {sound}!"

Für die Erzeugung einer Instanz müssen nun die Parameter übergeben werden.

luna = Dog2('Luna', 7)
luna.speak('Woof')
'Luna says Woof!'

Die beiden Instanzdaten-Attribute können nun einfach gelesen werden.

print(luna.name)
print(luna.age)
Luna
7

Wir können diese Attribute auch einfach schreiben.

luna.age = 9
print(luna.name)
print(luna.age)
Luna
9
class Dog3:
    # instance methode, __init__
    def __init__(self, name, age):
        self.name =  name # instance data attribute
        self.age = age # instance data attribute
        
    # instance methode
    def description(self):
        return f"{self.name} is {self.age} years old"
        
    # instance methode
    def speak(self, sound):
        return f"{self.name} says {sound}!"
charlie = Dog3('Charlie', 3)
charlie.description()
'Charlie is 3 years old'

__str__ und __repr__

charlie
<__main__.Dog3 at 0x7f44eaf2c1c0>
str(charlie)
'<__main__.Dog3 object at 0x7f44eaf2c1c0>'
print(charlie)
<__main__.Dog3 object at 0x7f44eaf2c1c0>
class Dog4:
    species = "Canis familiaris"
    
    def __init__(self, name, age):
        self.name = name
        self.age = age
    
    def __repr__(self):
        return f"{self.name} is {self.age} years old"
        
    # instance methode
    def description(self):
        return f"{self.name} is {self.age} years old"

    # Another instance method
    def speak(self, sound):
        return f"{self.name} says {sound}"
balu = Dog4('Balu', 5)
balu
Balu is 5 years old
str(balu)
'Balu is 5 years old'
print(charlie)
<__main__.Dog3 object at 0x7f44eaf2c1c0>
class Dog5:
    species = "Canis familiaris"
    
    def __init__(self, name, age):
        self.name = name
        self.age = age
    
    def __str__(self):
        return f"{self.name} is {self.age} years old"
        
    # instance methode
    def description(self):
        return f"{self.name} is {self.age} years old"

    # Another instance method
    def speak(self, sound):
        return f"{self.name} says {sound}"
rocky = Dog5('rocky', 5)
rocky
<__main__.Dog5 at 0x7f44eaec7f70>
str(rocky)
'rocky is 5 years old'
print(rocky)
rocky is 5 years old
class Dog6:
    species = "Canis familiaris"
    
    def __init__(self, name, age):
        self.name = name
        self.age = age
    
    def __repr__(self):
        return f"{self.name} is {self.age} years old"
        
    def __str__(self):
        return f"{self.name} is {self.age} years old"
        
    # instance methode
    def description(self):
        return f"{self.name} is {self.age} years old"

    # Another instance method
    def speak(self, sound):
        return f"{self.name} says {sound}"
buddy = Dog6('Buddy', 5)
buddy
Buddy is 5 years old
print(buddy)
Buddy is 5 years old

Gute Beispiel von Klassen

Hier wollen wir

class Car:
    """
    A class to represent a car.

    ...

    Attributes
    ----------
    color : str
        color of the car
    kilometers : int
        total kilometers of the car
    """
    
    def __init__(self, color, kilometers):
        """
        Constructs all the necessary attributes for the car object.

        Parameters
        ----------
            color : str
                color of the car
            kilometers : int
                total kilometers of the car
        """
        
        self.color = color
        self.kilometers = kilometers
        
    def __str__(self):
        return f"Das {self.color} Auto hat einen Kilometerstand von {self.kilometers}."
    
    def __repr__(self):
        return f"Das {self.color} Auto hat einen Kilometerstand von {self.kilometers}."
car1 = Car('rot', 18000)
car1
Das rot Auto hat einen Kilometerstand von 18000.
class Student:
    """
    A class to represent a student.

    ...

    Attributes
    ----------
    name : str
        name of the student
    semester : int
        current semester of the student
    """
    
    def __init__(self, name, semester):
        self.name = name
        self.semester = semester
        
    def __str__(self):
        return f"Der Student {self.name} studiert im {self.semester} Semester."
    
    def __repr__(self):
        return f"Der Student {self.name} studiert im {self.semester} Semester."
student1 = Student('Max Mustername',8)
student1
Der Student Max Mustername studiert im 8 Semester.
class Person:
    """
    A class to represent a person.

    ...

    Attributes
    ----------
    name : str
        first name of the person
    surname : str
        family name of the person
    age : int
        age of the person

    Methods
    -------
    info(additional=""):
        Prints the person's name and age.
    """

    def __init__(self, name, surname, age):
        """
        Constructs all the necessary attributes for the person object.

        Parameters
        ----------
            name : str
                first name of the person
            surname : str
                family name of the person
            age : int
                age of the person
        """

        self.name = name
        self.surname = surname
        self.age = age
        
    def __str__(self):
        return f'Mein Name lautet {self.name} {self.surname}. Ich min {self.age} Jahre alt.'
    
    def __repr__(self):
        return f'Mein Name lautet {self.name} {self.surname}. Ich min {self.age} Jahre alt.'
    

    def description(self, additional=""):
        """
        Prints the person's name and age.

        If the argument 'additional' is passed, then it is appended after the main info.

        Parameters
        ----------
        additional : str, optional
            More info to be displayed (default is None)

        Returns
        -------
        None
        """

        print(f'Mein Name lautet {self.name} {self.surname}. Ich min {self.age} Jahre alt.' + additional)
help(Student)
Help on class Student in module __main__:

class Student(builtins.object)
 |  Student(name, semester)
 |  
 |  Methods defined here:
 |  
 |  __init__(self, name, semester)
 |      Initialize self.  See help(type(self)) for accurate signature.
 |  
 |  __repr__(self)
 |      Return repr(self).
 |  
 |  __str__(self)
 |      Return str(self).
 |  
 |  ----------------------------------------------------------------------
 |  Data descriptors defined here:
 |  
 |  __dict__
 |      dictionary for instance variables (if defined)
 |  
 |  __weakref__
 |      list of weak references to the object (if defined)

Fazit

Wir haben minimale Klassen in Python kennengelernt und einige Beispiel von Klassen gesehen. Für erste eigene Implementierungen reichen diese Information.

Im nächsten Kapitel wollen wir die Mechanik Klassen und vor allen die Attribute sehr genau studieren.