Home | Lehre | Videos | Texte | Vorträge | Software | Person | Impressum, Datenschutzerklärung | ![]()
Stand: 2025-07-02
weitgehend formuliert von Claude 3.5 Sonnet, verbessert von ChatGPT 4o,
redigiert/korrigiert von Jörn Loviscach
Der Hauptzweck der Modularisierung ist es, komplexe Systeme in kleinere, überschaubare und wiederverwendbare Teile zu zerlegen. Dies bringt mehrere wichtige Vorteile mit sich:
Übersichtlichkeit und Wartbarkeit. Große Programme werden in kleinere, leichter verständliche Einheiten aufgeteilt. Dies macht den Code einfacher zu lesen, zu verstehen und zu warten. Änderungen lassen sich oft in einzelnen Modulen vornehmen, ohne das gesamte System zu beeinflussen.
Wiederverwendbarkeit. Gut gestaltete Module können in verschiedenen Projekten wiederverwendet werden. Dies spart Zeit und sorgt dafür, dass der Code öfter angewendet und damit getestet wird.
Arbeitsteilung und Zusammenarbeit. Verschiedene Entwickler oder Teams können gleichzeitig an unterschiedlichen Modulen arbeiten. Dies ermöglicht eine effizientere Entwicklung, besonders bei größeren Projekten.
Trennung von Zuständigkeiten. Jedes Modul kann sich auf eine spezifische Aufgabe oder Funktionalität konzentrieren. Dies fördert eine klare Struktur und erleichtert das Debuggen.
Abstraktion und Kapselung. Module können komplexe Funktionalitäten hinter einfachen Schnittstellen verbergen. Benutzer eines Moduls müssen nicht die internen Details verstehen, um es zu verwenden.
Skalierbarkeit. Modulare Systeme sind leichter zu erweitern und zu skalieren. Neue Funktionen implementiert man oft durch Hinzufügen neuer Module, ohne bestehenden Code stark zu verändern.
Testbarkeit. Einzelne Module können unabhängig voneinander getestet werden. Dies erleichtert das Schreiben von Tests und das Finden von Fehlern.
Flexibilität und Anpassbarkeit. Module lassen sich austauschen oder aktualisieren, ohne das gesamte System neu zu schreiben. Dies ermöglicht eine einfachere Anpassung an sich ändernde Anforderungen.
Ein Alltagsbeispiel zur Veranschaulichung: Ein Auto besteht aus vielen Modulen (Motor, Getriebe, Klimaanlage, Infotainmentsystem etc.). Jedes dieser Module
In der Softwareentwicklung funktioniert die Modularisierung ähnlich. Sie erlaubt es, komplexe Systeme zu erstellen, die dennoch flexibel, wartbar und erweiterbar bleiben. Gleichzeitig macht die Modularisierung die Softwareentwicklung effizienter, flexibler und nachhaltiger, besonders bei größeren und komplexeren Projekten.
In Python sind Module ganz normale
.py-Dateien. Angenommen,
wir haben ein Modul namens mathe_helfer.py mit folgendem
Inhalt:
def addiere(a, b):
return a + b
def multipliziere(a, b):
return a * bAlle Elemente (dazu gehören Variablen, Funktionen und Klassen) eines solchen Moduls können in anderen Python-Dateien verwendet werden – und damit auch in anderen Modulen verwendet werden.
In einem anderen Programm können wir dieses Modul nun so verwenden:
import mathe_helfer
ergebnis1 = mathe_helfer.addiere(5, 3)
ergebnis2 = mathe_helfer.multipliziere(4, 2)
print(ergebnis1) # Ausgabe: 8
print(ergebnis2) # Ausgabe: 8In dem Programm, das das Modul verwendet, muss man dann immer
mathe_helfer vor die Namen der verwendeten Elemente
schreiben. Das ist zwar übersichtlich, kann aber nerven.
Knapper ist der Import mit einem Alias
, hier
mh:
import mathe_helfer as mh
ergebnis1 = mh.addiere(5, 3)
ergebnis2 = mh.multipliziere(4, 2)
print(ergebnis1) # Ausgabe: 8
print(ergebnis2) # Ausgabe: 8Wenn man nur ausgewählte Elemente aus dem Modul benötigt, kann man
diese gezielt importieren und dann ohne Namenszusätze verwenden. Das
kann allerdings zu Namenskollisionen führen, zum Beispiel, wenn man in
der folgenden Beispieldatei noch eine eigene Funktion
addiere haben wollen würde:
from mathe_helfer import addiere, multipliziere
ergebnis1 = addiere(5, 3)
ergebnis2 = multipliziere(4, 2)
print(ergebnis1) # Ausgabe: 8
print(ergebnis2) # Ausgabe: 8Es ist zwar bequem, aber wegen der Gefahr von Namenskollisionen keine
gute Idee, einfach mit * alle Elemente eines Moduls (außer
denen, deren Name mit einem Unterstrich anfängt) zu importieren:
from mathe_helfer import *
ergebnis1 = addiere(5, 3)
ergebnis2 = multipliziere(4, 2)
print(ergebnis1) # Ausgabe: 8
print(ergebnis2) # Ausgabe: 8Im Prinzip kann ein import statt am Anfang einer
Python-Datei auch mitten im Programm stehen, sogar innerhalb eines
if. Aber Vorsicht damit!
Solche Bibliotheken wie Matplotlib und PySide wären für ein einziges Modul, das ja nur aus einer Datei besteht, viel zu komplex. Deshalb gibt es in Python noch eine höhere Ebene der Modularisierung, nämlich Packages. Der Import von Packages sieht äußerlich aus wie der oben beschriebene Import von Modulen.
Ein Package ist ein Verzeichnis, das mehrere Module enthält. Es
sollte eine spezielle Datei namens __init__.py enthalten.
Packages können auch Unter-Packages enthalten, was eine hierarchische
Strukturierung ermöglicht.
Python führt die Datei __init__.py wird beim Import des
Packages aus, so dass dort allgemeine Vorbereitungen getroffen werden
können. Ebenfalls lässt sich in jener Datei zum Beispiel festlegen,
welche Elemente mit dem (nicht empfohlenen!)
from ... import * importiert werden und welche nicht.
if __name__ == "__main__"In Python wird beim Ausführen eines Skripts automatisch eine
spezielle Variable namens __name__ gesetzt.
python mein_script.py), hat __name__ den Wert
"__main__".__name__ den Namen des Moduls (z. B.
"mein_script").Mit folgender Konstruktion kann man also sicherstellen, dass ein bestimmter Code nur beim direkten Ausführen der Datei, nicht aber beim Import, ausgeführt wird:
if __name__ == "__main__":
# Code, der nur beim direkten Ausführen laufen sollDas ist besonders nützlich, wenn man am Ende eines Moduls Beispielcode oder einfache Tests unterbringen will, die nicht jedes Mal mitlaufen sollen, wenn das Modul in einem anderen Programm importiert wird.
Beispiel:
# datei: mathe_helfer.py
def addiere(a, b):
return a + b
def multipliziere(a, b):
return a * b
if __name__ == "__main__":
# Beispielhafte Nutzung und einfacher Test
print(addiere(2, 3)) # Ausgabe: 5
print(multipliziere(4, 5)) # Ausgabe: 20Wird mathe_helfer.py importiert, z. B. mit
import mathe_helfer, werden nur die Funktionen
geladen. Der Code im if __name__ == "__main__"-Block wird
dann nicht ausgeführt – genau das gewünschte Verhalten bei
wiederverwendbaren Modulen.