Python Tutorial, Teil 6 Py-Module und Bibliotheken
Python erlaubt die Modularisierung eigener Code-Bestandteile und das Einbinden von Standardmodulen über Bibliotheken. Wie Module, Skripts, Libraries und Pakete zusammenhängen, beleuchtet dieser sechste Teil unseres Tutorials.
Anbieter zum Thema

Im bisherigen Verlauf des Workshops wurde Python-Code überwiegend direkt im Python-Interpreter ausgeführt. Grundsätzlich hat es dazu ausgerecht, den Code in einer beliebigen Textdatei niederzuschreiben und bei Bedarf per Copy-and-Paste in einen Online-Interpreter wie repl.it zu kopieren. Das ist freilich nur bei kurzen Demo-Programmen akzeptabel.
Längere und komplexere Anwendungen oder deren Bestandteile legt man in Python üblicherweise in .py-Dateien ab. Hierbei handelt es sich im Prinzip um gewöhnliche Textdateien, die den Python-Quelltext enthalten und mit jedem gewöhnlichen Texteditor bearbeitet werden können. Optimal ist ein Editor mit Auszeichnungsmodus für Python-Code wie z. B. Notepad++. Doch was hat es genau mit der Endung .py auf sich?
Über Module
Beendet der Nutzer seinen Python-Interpreter, gehen zwangsläufig sämtliche Definitionen wie Funktionen und Variablen verloren. Schon deshalb ist es sinnvoll, den Code zumindest in einer Textdatei festzuhalten bzw. zu entwickeln.
Im Grunde ist es so, dass diese Datei als Standard-Eingabe für den Interpreter fungiert, weshalb sie strenggenommen in die Kategorie Skript fällt. Längere und komplexere Programme teilt man dann der einfacheren Pflege und Wartbarkeit halber in mehrere Dateien auf. Die Aufteilung erlaubt aber nebenbei auch eine Mehrfachverwendbarkeit einmal definierter Funktionen in mehreren Programmen.
Python bietet dazu die Möglichkeit, in einer Datei bestimmte Definitionen wie z. B. Funktionen vorzunehmen und diese dann in einer anderen Datei zu verwenden/referenzieren. Konkret wird eine solche Datei dann Modul genannt, wobei sich die darin vorgenommenen Definitionen in andere Module oder in das so genannte Haupt-Modul importieren lassen.
Das Haupt-Modul enthält letztlich die Gesamtheit aller Funktionen und Variablen, auf die der Nutzer in einem Skript zugreifen kann. Somit ist jede (Text-)Datei, die Python-Anweisungen und/oder -Definitionen enthält, ein Modul, sobald sie die Dateiendung .py verwendet. Der Dateiname ist dann gleichbedeutend mit dem Modul-Namen. Das Einbinden eines Moduls in den Interpreter erfolgt über den Modulnamen (ohne Angabe der Endung .py).
import <modulname>
Die im Modul <modulname> definierten Funktionen werden dabei allerdings nicht automatisch in die globale Symbol-Tabelle eingefügt, sondern lediglich der Modulname. Möchte man eine im Modul <modulname> definierte Funktion im Interpreter ansprechen, verwendet man den Aufruf:
<modulname>.<Funktionsname>
Möchte man wissen, welche Funktion(en) im Modul <modulname> bekannt ist nutzt man ...
<modulname>.__name__
..., wobei „__name__“ eine globale Variable von Typ String ist. Soll eine Funktion öfter verwendet werden, bindet man sie im Interpreter an einen lokalen Namen:
<Funktionsname> = <modulname>.<Funktionsname>
Modul-Arten
Verallgemeinern wir das eben Gesagte zum Thema Module in Python. Das Schreiben gut lesbaren, gut wartbaren und zuverlässigen Codes ist ohne modulares Software-Design unmöglich, gerade bei größeren Software-Projekten. Die Idee der modularen Programmierung besteht darin, Programme systematisch in logische Teilblöcke, die so genannten Module aufzuteilen.
Python kennt allerdings zwei unterschiedliche Arten von Modulen:
- 1. Lokale Module: Diese sind nur für ein Programm verfügbar
- 2. Bibliotheken: Libraries hingegen stellen Datentypen oder Funktionen für sämtliche Python-Programme bereit. Dabei unterscheidet man wiederum:
- die sehr umfangreiche Standardbibliothek
- die oben illustrierten eigenen Module
- Module von Drittanbietern
Alle Module werden wie oben gesehen per import-Anweisung eingebunden. So bietet z. B. das Modul „math“ aus der Python-Standardbibliothek mathematische Konstanten und Funktionen, etwa die Sinus-Funktion math.sin(), die Cosinus-Funktion math.cos() oder die mathematische Konstante π mittels math.pi.
Für die folgenden Übungen verabschieden wir uns von Online-Interpreter Repl.it und installieren Python 3.7 für Windows von Python.org durch Herunterladen und Ausführen von „python-3.7.0a1-webinstall.exe“. Wir starten im Interpreter-Modus durch Aufruf von „python“ in der CMD oder Powershell und Experimentieren mit dem Modul „math“. So liefert z. B.
>>> math.pi
3.141592653589793
>>> math.sin(math.pi/2)
1.0
>>> math.cos(math.pi)
-1.0
Selbstverständlich kann man unter Python auch mehrere Module innerhalb einer Anweisung importieren ...
import math, statistics, random, numbers
…, wobei import-Anweisungen prinzipiell an jeder beliebigen Position des Quellcodes stehen können. Es hat sich aber aus Gründen der Übersichtlichkeit eingebürgert, Import-Anweisungen immer am Anfang zu verwenden.
Namensräume
Vor der Verwendung von Modulen sollte man sich mit dem Wirkungsbereich der Namensräume auseinandersetzen. Wie eingangs beschreiben ist der Name eines Moduls nach dem Importieren mit „Import math“ zunächst nur im eigenen Namensraum verfügbar. Das ist auch der Grund dafür, warum wir im Beispiel nur über den vollen Namen aus Modul- und Funktionsnamen beispielsweise auf die sin-Funktion zugreifen konnten.
Im Übrigen ist es zum Verwenden der sin-Funktion auch nicht zwingend erforderlich, das ganze math-Modul zu importieren. Optional ist es wie folgt auch möglich, nur die sin-Funktion selbst zu importieren:
from math import sin
Dann stehen die übrigen Funktionen der math-Bibliotheken im aktuellen Namensraum nicht zur Verfügung. Außerdem ist es möglich, eine „Bibliothek“ vollständig in den globalen Namensraum einzubinden, wobei allerdings unter Umständen bereits vorhandene Namen überschrieben werden. Bindet man also alle Funktionen von math mit ...
from math import *
... in den globalen Namensraum ein, passiert Folgendes. Angenommen, der Nutzer verwendet bereits eine eigene Variable pi mit dem Wert 3.14, so wird diese beim Import überschrieben. Daher liefert der Wert von pi anschließend:
>>>>print (pi)
3.14159265359
Deshalb ist es möglich, beim Importieren einer Bibliothek auch einen neuen Namen für den zu verwendenden Namensraum zu wählen. So könnte man z. B. die Bibliothek math unter Verwendung des Namensraums „ma“ importieren.
>>> import math as ma
>>> ma.pi
3.141592653589793
Übrigens akzeptiert Python wie in Teil 1 bereits erwähnt nicht nur in Python selbst geschrieben Module, zu erkennen an der Endung .py, sondern auch dynamisch geladene C-Module, die man an Endungen wie .dll, .pyd, .so, .sl, und weiteren erkennt. Ferner gib es C-Module, die mit dem Interpreter gelinkt sind. Welche das sind, findet man durch Eingeben von ...
>>>import sys
>>>print (sys.builtin_module_names)
... heraus. Eine weitere recht nützliche in der Standard-Bibliothek eingebaute Funktion ist dir (). Mit ihr kann man herauszufinden, welche Namen in einem Modul definiert sind. Die Funktion dir () liefert eine sortierte Liste von Strings zurück. Ohne weitere Parameter erhält man eine Liste der aktuell definierten Namen:
>>> dir ()
>>>['__annotations__', '__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'sys']
Suchpfade
Importiert der Nutzer ein Modul mit dem Namen <name>, sucht der Interpreter stets zuerst im aktuellen Verzeichnis nach einer Datei mit dem Namen <name>.py, danach in der Verzeichnisliste, die in der Umgebungsvariable PYTHONPATH gesetzt ist. Diese unterliegt der gleichen Syntax wie die Shell Variable PATH.
Ist PYTHONPATH nicht gesetzt ist oder wurde sie nicht gefunden, setzt der Interpreter die Suche in einem installationsabhängigen Pfad fort; der z. B. unter Unix normalerweise: /usr/local/lib/python lautet. Da diese Suchreihenfolge in der Variable sys.path festgehalten ist, können Python-Programmen die Suchpfade bei Bedarf verändern, ersetzen oder die Reihenfolge ändern.
Pakete
Mehrere Module lassen sich darüber hinaus auch zu einem Paket (package) zusammenfassen. So kann man im Prinzip den Modul-Namensraum von Python strukturieren, indem man Modulnamen durch Punkte trennt. Ein Paket ist dabei zunächst ein Verzeichnis, das Python-Module enthält sowie eine Datei mit dem Namen „__init__.py“. Diese Datei kann entweder leer sein oder Python-Code enthalten der bei Import des Paketes ausgeführt werden soll. Pakete selbst werden genau wie normale Module importiert, mit ihnen befassen wir uns in Teil 7 dieses Tutorials.
(ID:45215033)