Zum Inhalt

Modularisierung

Die Modularisierung von Quellcode ermöglicht es Funktionen oder Klassen an unterschiedlichen Stellen eines Programms wiederzuverwenden. Darüberhinaus können Funktionen oder Klassen im Kontext von Paketen sogar in andere Programme integriert werden oder aus anderen Programmen geladen werden.

Der Begriff Modul ist in der Softwareentwicklung nicht einheitlich definiert. Generell steht der Begriff für eine eigenständige Komponente innerhalb eines größeren Programms. Im Kontext von Python ist der Begriff Modul konkret definiert. Ein Modul entspricht dabei dem Inhalt einer Python Datei. Kurz gesagt eine .py Datei ist ein Modul in Python.

Beispiel: Modularisierung

Es wurde die Datei distance_functions.py erzeugt, welche unterschiedliche Implementierung von gängigen Distanzfunktionen enthält. Als Beispiel die Euklidische- und die Manhatten Distanz:

# Inhalt der Datei distance_functions.py

def euclidean_distance(point1=[], point2=[]):
    return sum((p - q) ** 2 for p, q in zip(point1, point2)) ** 0.5

def manhatten_distance(point1=[], point2=[]):
    return sum(abs(p - q) for p, q in zip(point1, point2))

# weitere Implementierungen ...    

Innerhalb einer zweiten Datei main.py, welche im selben Ordner liegt, können die Funktionen der Datei distance_functions.py importiert werden. Der Dateiname definiert damit auch den Modulname distance_functions. Mit dem Schlüsselwort import wird der Import des Moduls durchgeführt. Auf die Inhalte eines Moduls kann mit dem Dot-Operator zugegriffen werden.

# Inhalt der Datei main.py

import distance_functions

dist = distance_functions.euclidean_distance([1, 2], [3, 4])
print(dist)  # 2.828427...

Import Syntax

Python definiert unterschiedliche Schreibweisen um Inhalte eines Moduls zu importieren. Wichtig dabei sind die Schlüsselwörter import, from und as.

Die Default Schreibweise wäre die ausschließliche Nutzung des import Schlüsselwortes:

import distance_functions
distance_functions.euclidean_distance([1, 2], [3, 4])

Alias für Namensraum mit as

Mit dem Schlüsselwort as kann ein Alias für den Modulnamen vergeben werden. Der Vorteil des Alias ist, dass der lange Modulname distance_functions gekürzt werden kann:

import distance_functions as df
df.euclidean_distance([1, 2], [3, 4])

Das Modul distance_functions wird im importierenden Modul unter dem Bezeichner df bekannt gemacht. df ist der definierte Alias vom vollständigen Modulnamen distance_functions.

Ausgewählte Bestandteile mit from importieren

Mit dem Schlüsselwort from können ausgewählte Bestandteile des Moduls in den aktuellen Namensraum bzw. in das aktuelle Modul importiert werden.

from distance_functions import euclidean_distance, manhattan_distance
euclidean_distance([1, 2], [3, 4])
manhattan_distance([1, 2], [3, 4])

Aus dem Modul distance_functions werden explizit nur die Funktionen euclidean_distance und manhatten_distance importiert. Diese können somit auch ohne Modul-Prefix (zB distance_functions.euclidean_distance) verwendet werden.

Namenskonflikte

Bei dieser Art des Import kann es zu Namenskonflikten kommen. Beispielsweise könnte dies passieren, wenn im importierenden Modul bereits eine Funktion euclidean_distance definiert wird.

Alles mit * importieren

Durch die Angabe eines * können alle Bestandteile eines Modules in den aktuellen Namensraum importiert werden. Der * sollte nur verwendet werden, wenn die Bestandteile des Moduls bekannt sind und wirklich alle geladen werden sollen. Ebenfalls sollte man mögliche Namenskonflikte bedenken.

from distance_functions import *

Alias für Importe mit as

Mit dem Schlüsselwort as kann auch eine Funktion oder Klasse die importiert werden soll mit einem Alias definiert werden:

from distance_functions import euclidean_distance as ed
ed([1, 2], [3, 4])

Python Standardbibliothek

Mit Installation von Python wird auch die Python Standardbibliothek mitgeliefert. Darin befindet sich eine Menge von nützlichen Modulen, welche innerhalb eigener Programme importiert werden können.

Eine vollständige Übersicht über alle Module der Standardbibliothek findet sich in der Python Dokumentation. Im folgenden soll exemplarisch, anhand des random Moduls, gezeigt werden wie Module der Standardbibliothek genutzt werden können.

random Modul

Das random Modul stellt nützliche Funktionen bereit um Zufallszahlen zu erzeugen.

Im folgenden Beispiel wird das Modul random importiert und mit den zwei Funktionen random bzw. randint werden Zufallszahlen erzeugt. Das Modul bietet eine Vielzahl weiterer Funktionen, welche über die Dokumentation beschrieben werden.

import random

print(random.random())  # float Zufallszahl zwischen 0 und 1

print(random.randint(0, 9))  # int Zufallszahl zwischen 0 und 9

Random Seed

Ein Generator von Zufallszahlen benötigt einen Seed. Anhand dieses Seed werden Zufallszahlen sequenziell errechnet. Als Defaultwert wird der Seed gerne über den aktuellen Timestamp initialisiert. Um einen Zufallszahlengenerator deterministischer zu machen und zB Replizierbarkeit für ein Notebook herzustellen, kann ein Seed explizit gesetzt werden.

import random

random.seed(99)

print(random.random())  # 0.40397807494366633
print(random.random())  # 0.20007544457494542
print(random.random())  # 0.17880232058661227

Durch das setzen des beliebigen Seeds 99 würde auch das mehrmalige Ausführen des Programms immer dieselben Zufallszahlen generieren.

Python Package

Um Module in eine größere Einheit zusammen zu fassen können Packages erzeugt werden. Ein Python Package ist dabei "einfach gesprochen" ein Ordner im Dateisystem, welcher eine Datei __init__.py enthält.

Tiefergehendes Verständnis für Python Packages ist vor allem wichtig, wenn man eigene Bibliotheken entwickeln möchte. Dies würde den Rahmen der LV sprengen, deshalb wird hier auf weiterführende Dokumentation verwiesen.

Freie (unter FOSS Lizenzen verteilt) Python Packages können als Bibliotheken über einen Paketmanager (zb pip) integriert werden. Im Python Package Index finden sich alle freien Python Packages.