Modularisierung
Module
Modulare Programmierung ist eine Seftware-Design-Technik, die auf dem allgemeinen Prinzip
des modularen Designs beruht. Modulares Design ist ein Ansatz, der sich als unausweichlich und
unentbehrlich schon lange vor den ersten Computern im Ingenieurwesen herausgestellt hat.
Unter modularem Design versteht man, dass man ein komplexes System in kleinere selbständige Einheiten
oder Komponenten zerlegt. Diese Komponenten bezeichnet man üblicherweise als Module. Ein Modul
kann unabhängig vom Gesamtsystem erzeugt und separat getestet werden. In den meisten Fällen kann man
ein Modul auch in anderen Systemen verwenden.
Heutzutage gibt es kaum ein Produkt, das nicht auf Modularisierung beruht, so wie Autos, Mobiltelefone,
und so weiter. Computer gehören zu den Produkten, die bis zum Äußersten modularisiert sind.
Das was für die Hardware ein Muss ist, stellt auch für die Software, die auf ihr läuft, eine
unvermeidliche Notwendigkeit dar.
Wenn man Programme schreiben will, die lesbar, zuverlässig und und ohne hohen Aufwand wartbar sind,
geht es nicht ohne modulares Software-Design, insbesondere bei größeren Software-Projekten.
Es gibt verschiedene Konzepte um Programme modular zu gestalten.
Der Ansatz der modularen Programmierung besteht darin, Programme systematisch in logische Teilblöcke,
d.h. Module, aufzuspalten. Die Aufteilung eines Quelltextes in einzelne Teile (Module) bezeichnet man
als Modularisierung.
In Python unterscheiden wir zwei Arten von Modulen:
-
Bibliotheken (Libraries)
Stellen Datentypen oder Funktionen für alle Python-Programme bereit.
Es gibt:- die umfangreiche Standbibliothek
- eigene Bibliotheken
- Bibliothek von Drittanbieter
- lokale Module
nur für ein Programm verfügbar
Beispiel:
import mathDas Modul math aus der Standardbibliothek stellt mathematische Konstanten und Funktionen zur Verfügung.
Nach dem Schlüsselwort import können auch mehrere durch Komma getrennte Modulnamen folgen:
import math, randomimport-Anweisungen können an jeder Stelle des Quellcodes stehen, aber man sollte sie der Übersichtlichkeit willen an den Anfang stellen.
Namensräume der Bibliotheken
Wird eine Bibliothek importiert, wie z.B.
import mathdann stehen die Namen der Bibliothek in einem eigenen Namensraum zur Verfügung.
Auf die sin()-Funktion von math kann man zunächst nur über den vollen Namen ("fully qualified") zugreifen, d.h.
math.sin(x)Man kann auch selektiv nur einzelne Methoden/Funktionen importieren:
from math import sin, piDie anderen Methoden der Bibliothek stehen dann nicht zur Verfügung. Auf sin und pi kann man aber direkt (ohne math.) zugreifen.
Man kann auch eine Bibliothek komplett in den globalen Namensraum einbinden. Dabei werden dann gegebenenfalls bereits vorhande gleichlautende Namen überschrieben, wie dies im folgenden Beispiel geschieht:
>>> pi = 3.142 >>> print(pi) 3.142 >>> from math import * >>> print(pi) 3.14159265359 >>>
Umbenennen des Namensraumes beim Import
Beim Import einer Bibliothek kann man auch einen neuen Namen für den Namensraum wählen:
>>> import math as mathematik >>> print(mathematik.cos(mathematik.pi)) -1.0Ein Namensraum math existiert in obigem Beispiel nicht, sondern nur ein Namensraum mathematik.
Im folgenden Beispiel werden einzelne Methoden des math-Moduls umbenannt, so werden pow() in power() und sin() in sinus() umbenannt:
>>> from math import pi,pow as power, sin as sinus >>> power(2,3) 8.0 >>> sinus(pi) 1.2246467991473532e-16
Modul-Arten
Es gibt verschiedene Modul-Arten:
- in Python geschrieben
Endung: .py - Dynamisch geladene C-Module
Endung: .dll, .pyd, .so, .sl, usw. - C-Module, die mit dem Interpretor gelinkt sind:
Um eine Liste dieser Module zu erhalten:import sys print(sys.builtin_module_names)
Falls es sich um ein Built-in-Modul handelt, erhält man eine Fehlermeldung.
Suchpfad für Module
Wenn man ein Modul z.B. abc importiert, sucht der Interpretor nach abc.py in der folgenden Reihenfolge:
- Im aktuellen Verzeichnis
- PYTHONPATH
- Falls PYTHONPATH nicht gesetzt ist, wird installationsabhängig im Default-Pfad gesucht, also unter Linux/Unix z.B. in /usr/lib/python2.5.
Inhalt eines Moduls
Mit der build-in-Funktion dir() kann man sich die in einem Modul definierten Namen ausgeben lassen.
>>> dir(math) ['__doc__', '__file__', '__name__', 'acos', 'asin', 'atan', 'atan2', 'ceil', 'cos', 'cosh', 'degrees', 'e', 'exp', 'fabs', 'floor', 'fmod', 'frexp', 'hypot', 'ldexp', 'log', 'log10', 'modf', 'pi', 'pow', 'radians', 'sin', 'sinh', 'sqrt', 'tan', 'tanh'] >>>Ohne Argumente liefert dir() die definierten Namen
>>> import math >>> col = ["red","green","blue"] >>> dir() ['__builtins__', '__doc__', '__name__', 'col', 'math']
Eigene Module
Die beiden folgenden Funktionen fib(), die den n-ten Fibonacci-Wert zurückliefert, und die Funktion fiblist() werden in einer Datei fibonacci.py gespeichert.
def fib(n):
a, b = 0, 1
for i in range(n):
a, b = b, a + b
return a
def fiblist(n):
fib = [0,1]
for i in range(1,n):
fib += [fib[-1]+fib[-2]]
return fib
Von einem anderen Programm oder von der interaktiven Shell kann man nun, falls
fibonacci.py innerhalb des Suchpfades zu finden ist, die Datei mit den beiden
Fibonacci-Funktionen als Modul aufrufen.
>>> import fibonacci >>> fibonacci.fib(10) 55 >>> fibonacci.fiblist(10) [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55] >>> fibonacci.__name__ 'fibonacci' >>>
Eigene Module
Python ermöglicht es, dass man mehrere Module in einem Paket kapseln kann. Ein
Paket kann beliebig viele weitere Pakete enthalten.
Um ein Paket zu erstellen, muss im Wesentlichen ein Unterordner erzeugt werden. In diesem Ordner muss dann eine Datei mit
dem Namen
__init__.py
existieren.
Die Datei kann leer
sein oder Initiali-
sierungscode ent-
halten, der beim
Einbindenbinden des Paketes einmalig ausgeführt wird.

