Eine Einführung in die objektorientierte Programmierung

Eine ausführliche Beschreibung finden Sie hier: https://www.python-kurs.eu/klassen.php

Wir haben bereits vordefinierte Objekte und Methoden von Klassen benutzt.

In [1]:
liste1 = [1,2,3]
In [2]:
liste1  # liste1. + TAB Taste
Out[2]:
[1, 2, 3]
In [3]:
a = -23
type(a)
dir(a)
Out[3]:
['__abs__',
 '__add__',
 '__and__',
 '__bool__',
 '__ceil__',
 '__class__',
 '__delattr__',
 '__dir__',
 '__divmod__',
 '__doc__',
 '__eq__',
 '__float__',
 '__floor__',
 '__floordiv__',
 '__format__',
 '__ge__',
 '__getattribute__',
 '__getnewargs__',
 '__gt__',
 '__hash__',
 '__index__',
 '__init__',
 '__init_subclass__',
 '__int__',
 '__invert__',
 '__le__',
 '__lshift__',
 '__lt__',
 '__mod__',
 '__mul__',
 '__ne__',
 '__neg__',
 '__new__',
 '__or__',
 '__pos__',
 '__pow__',
 '__radd__',
 '__rand__',
 '__rdivmod__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__rfloordiv__',
 '__rlshift__',
 '__rmod__',
 '__rmul__',
 '__ror__',
 '__round__',
 '__rpow__',
 '__rrshift__',
 '__rshift__',
 '__rsub__',
 '__rtruediv__',
 '__rxor__',
 '__setattr__',
 '__sizeof__',
 '__str__',
 '__sub__',
 '__subclasshook__',
 '__truediv__',
 '__trunc__',
 '__xor__',
 'bit_length',
 'conjugate',
 'denominator',
 'from_bytes',
 'imag',
 'numerator',
 'real',
 'to_bytes']

Eine erste Klasse, die nichts kann.

Die minimale Definition einer Klasse in Python hat die Form

In [4]:
class ErsteKlasse(object):
    pass # pass gibt an, dass hier noch irgendwas hin soll
In [5]:
p = ErsteKlasse()
p
Out[5]:
<__main__.ErsteKlasse at 0x7fea54629b38>
In [6]:
class ZweiteKlasse(object):
    """ eine zweite Klasse """
    n = 1234
    def f(x):
        return x**2

z = ZweiteKlasse
z
dir(z)
Out[6]:
['__class__',
 '__delattr__',
 '__dict__',
 '__dir__',
 '__doc__',
 '__eq__',
 '__format__',
 '__ge__',
 '__getattribute__',
 '__gt__',
 '__hash__',
 '__init__',
 '__init_subclass__',
 '__le__',
 '__lt__',
 '__module__',
 '__ne__',
 '__new__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__setattr__',
 '__sizeof__',
 '__str__',
 '__subclasshook__',
 '__weakref__',
 'f',
 'n']

Klasse Student

In [7]:
class Student(object):
    
    noten = []                      # 
    
    def __init__(self,Vn,Nn,MatNr):
        self.Vorname = Vn
        self.Nachname = Nn
        self.MatrikelNummer = MatNr
    #'__init__ wird automatisch beim Erstellen eines Objektes aufgerufen

    # Klassenmethoden
    def notehinzufuegen(self,note):
        self.noten.append(note)
        
    def hallo(self):
        print('Hallo mein Name ist {0} {1}'.format(self.Vorname,self.Nachname))
 
           
a = Student('Li','Ping',101)
b = Student('Lisa','Paul',102)
a.notehinzufuegen(1)
b.notehinzufuegen(4)

print('Hallo {0} {1}'.format(a.Vorname,a.Nachname))
a.hallo()
b.hallo()

a.noten
Hallo Li Ping
Hallo mein Name ist Li Ping
Hallo mein Name ist Lisa Paul
Out[7]:
[1, 4]

Bessere Lösung

In [8]:
class Student(object):
     
    def __init__(self,Vn,Nn,MatNr):
        self.Vorname = Vn
        self.Nachname = Nn
        self.MatrikelNummer = MatNr
        self.noten = []
        
    def notehinzufuegen(self,note):
        self.noten.append(note)
        
    def hallo(self):
        print('Hallo mein Name ist {0} {1}'.format(self.Vorname,self.Nachname))
 
In [9]:
a = Student('Li','Ping',101)
b = Student('Lisa','Paul',102)
a.notehinzufuegen(1)
b.notehinzufuegen(4)

a.noten, b.noten
Out[9]:
([1], [4])

Rules regarding self

(from Lantangen's book, page 419):

1) Any class method must have self as first argument. (The name can be any valid variable name, but the name self is a widely established convention in Python.)

2) self represents an (arbitrary) instance of the class.

3) To access any class attribute inside class methods, we must prefix with self, as in self.name, where name is the name of the attribute.

4) self is dropped as argument in calls to class methods.

In [10]:
class Student(object):
    
    def __init__(self,Vn,Nn,MatNr):
        self.Vorname = Vn
        self.Nachname = Nn
        self.MatrikelNummer = MatNr
        self.noten = []
        
    def saghallo(self):
        print('Hallo mein Name ist {0} {1}'.format(self.Vorname,self.Nachname))
 
    def brief(self):
        return 'HALLO {0} Deine email ist {1}'.format(self.Vorname,self.email())
        
    def email(self):
        return '{0}.{1}@hhu.de'.format(self.Vorname,self.Nachname)
            
a = Student('Li','Ping',101)
b = Student('Lisa','Paul',102)
a.saghallo()
print(a.brief())
Hallo mein Name ist Li Ping
HALLO Li Deine email ist Li.Ping@hhu.de

Ein mathematisches Beispiel

Eine Klasse für Polynome

In [11]:
class Polynom(object):
    """ Polynomklasse Beschreibung .....
    """
    def __init__(self,dp):
        if isinstance(dp,(int,float,complex)):
            dp = {0:dp}
        self.dp = dp
        self.degree = max(dp.keys())
        
    def __repr__(self):
        polystr = ''
        for k in sorted(self.dp):
            polystr = polystr + '{0:+g}*X^{1}'.format(self.dp[k],k)
        return 'Polynom: ' + polystr 
    
    def __add__(self,other):
        spow = set(self.dp.keys())
        opow = set(other.dp.keys())
        pows = spow.union(opow)
        pps = dict()
        for k in pows:
            if k in spow:
                if k in opow:
                    pps[k] = self.dp[k] + other.dp[k]
                else:
                    pps[k] = self.dp[k]
            else:
                pps[k] =  other.dp[k]
        
        return Polynom(pps)
    
    def __sub__(self,other):
        """ Substraktion zweier Polynomen 
        """
        selfpow = set(self.dp.keys())
        otherpow = set(other.dp.keys())
        pows = selfpow.union(otherpow)
        erg = dict()
        for k in pows:
            if k in selfpow:
                if k in otherpow:
                    erg[k] = self.dp[k] - other.dp[k]
                else:
                    erg[k] = self.dp[k]
            else:
                erg[k] =  -other.dp[k]
        
        return Polynom(erg)
    def __call__(self,x):
        """ Auswertung des Polynoms 
        """
        return sum([self.dp[k]*x**k for k in self.dp])
    
    def __mul__(self,other):
        """ Multiplikation eines Polynoms mit einem Skalar 
        TODO Polynommultiplikation
        """
        erg = dict()
        if isinstance(other,(int,float,complex)):
            for k in self.dp:
                erg[k] = self.dp[k] *other       
            return Polynom(erg)
        
    __rmul__ = __mul__
            
In [12]:
pd = {0:1,10:2.5}
qd = {0:2/3,5:34}
p = Polynom(pd)
q = Polynom(qd)
p, q
Out[12]:
(Polynom: +1*X^0+2.5*X^10, Polynom: +0.666667*X^0+34*X^5)
In [13]:
print(p)
Polynom: +1*X^0+2.5*X^10
In [14]:
p+q
Out[14]:
Polynom: +1.66667*X^0+34*X^5+2.5*X^10
In [15]:
p-q
Out[15]:
Polynom: +0.333333*X^0-34*X^5+2.5*X^10
In [16]:
2*p
Out[16]:
Polynom: +2*X^0+5*X^10
In [17]:
p*2
Out[17]:
Polynom: +2*X^0+5*X^10
In [18]:
2*p+q
Out[18]:
Polynom: +2.66667*X^0+34*X^5+5*X^10
In [19]:
p(2)
Out[19]:
2561.0