Module
Je komplexer unsere Applikation wird, desto grösser wird auch die entsprechende Python-Datei. Irgendwann steht dort so viel Code drin, dass wir uns kaum mehr zurechtfinden.
Da kommen Module ins Spiel: Sie erlauben es uns, ein Programm auf mehrere Python-Dateien zu verteilen.
Für dieses Beispiel gehen wir davon aus, dass wir eine Datei rechner.py mit folgendem Code haben:
def plus(a, b):
print(a + b)
def minus(a, b):
print(a - b)
def mal(a, b):
print(a * b)
def durch(a, b):
print(a / b)
plus(10, 5)
minus(10, 5)
durch(10, 5)
Module erstellen
Um unser Programm übersichtlicher zu gestalten, könnten wir nun beispielsweise die Funktionen plus() und minus() in eine Datei strich_operationen.py und die Funktionen mal() und durch() in eine Datei punkt_operationen.py verschieben. Diese beiden Dateien sehen also folgendermassen aus:
strich_operationen.py:
def plus(a, b):
print(a + b)
def minus(a, b):
print(a - b)
punkt_operationen.py:
def mal(a, b):
print(a * b)
def durch(a, b):
print(a / b)
Damit haben wir zwei neue Module erstellt: strich_operationen und punkt_operationen.
Jede Python-Datei ist auch ein Modul. Ihr Modulname entspricht ihrem Dateinamen ohne die .py-Endung.
Sprich: Die Datei strich_operationen.py ist zugleich ein Modul namens strich_operationen, punkt_operationen.py ist zugleich ein Modul namens punkt_operationen.
Module verwenden
Unser ursprüngliches Programm können wir nun wie folgt vereinfachen:
rechner.py:
plus(10, 5)
minus(10, 5)
durch(10, 5)
Doch etwas fehlt noch: Wir müssen Python noch mitteilen, dass wir die Funktionen aus den beiden neuen Modulen verwenden wollen. Das machen wir mit einem import.
Den Import kennen Sie bereits aus der Turtle-Zeit: from turtle import *. Damit sagen wir Python, dass wir:
from turtle- aus dem Turtle-Modul
import *1- sämtliche Funktionen und Variablen importieren wollen.
Analog importieren wir die beiden Module strich_operationen und punkt_operationen:
rechner.py:
from strich_operationen import *
from punkt_operationen import *
plus(10, 5)
minus(10, 5)
durch(10, 5)
Damit dieser Import funktioniert, müssen alle drei Dateien nebeneinander liegen (also im gleichen Ordner gespeichert sein)!2.
Nun funktioniert unser Rechner auch wieder korrekt und verwendet die Funktionen aus unseren neuen Modulen.
Gegeben ist folgendes Python-Programm:
def hallo():
print("Hallo!")
def hi():
print("Hi!")
def wetter():
print("Der Tag heute wird sonnig und warm.")
def temperatur():
print("Die Temperatur beträgt ca. 25 °C")
def verabschiedung_1():
print("Auf Wiedersehen!")
def verabschiedung_2():
print("Tschüss!")
hi()
wetter()
temperatur()
verabschiedung_1()
Erstellen Sie einen neuen Ordner für diese Übung und öffnen Sie diesen in VSCode. Erstellen Sie darin eine Datei main.py und kopieren Sie den obigen Code hinein.
Optimieren Sie dann das Programm, indem Sie die definierten Funktionen in drei Module aufteilen:
- Ein Modul enthält die Begrüssungen
hallo()undhi(). - Ein zweites Modul enthält die Wetter-Infos
wetter()undtemperatur(). - Ein drittes Modul enthält die Verabschiedungen
verabschiedung_1()undverabschiedung_2().
Verwenden Sie in main.py anschliessend die entsprechenden import-Statements, um die drei Module zu importieren, so dass die Ausgabe am Schluss wieder gleich funktioniert wie zuvor (ausführen mit python main.py im VSCode-Terminal):
# Hier kommen Ihre Importe hin
# Hier hat es KEINE Funktionsdefinitionen (def) mehr
hi()
wetter()
temperatur()
verabschiedung_1()
Bei der Benennung von Modulen (also .py-Dateien) gelten in Python fogelnde Regeln:
- Der Modulname darf nur aus Buchstaben, Zahlen und Unterstrichen (
_) bestehen - Der Modulname darf nicht mit einer Zahl beginnen
- Der Modulname darf keine Leerzeichen enthalten
Import optimieren
Tatsächlich verwenden wir aus dem modul punkt_operationen eigentlich nur die Funktion durch(). Mit dem aktuellen Import auf Zeile 2 im vorherigen Code-Ausschnitt importieren wir aber alle Funktionen aus punkt_operationen — also auch die Funktion mal(), welche wir momentan gar nicht brauchen.
In Python gehört es zur Best Practice (empfohlene Vorgehensweise), dass wir nur die Dinge importieren, die wir auch wirklich benötigen. Das machen wir, indem wir den import nicht überall mit import * spezifizieren, sondern dort genau diejenigen Dinge auflisten, die wir benötigen.
from strich_operationen import plus, minus
from punkt_operationen import durch
plus(10, 5)
minus(10, 5)
durch(10, 5)
Da wir aus dem Modul strich_operationen alle Funktionen benötigen, ist der Import auf Zeile 1 in diesem spezifischen Fall gleichwertig mit from strich_operationen import *.
Optimieren Sie die Importe in Ihrem Programm aus der vorherigen Aufgabe so, dass nur noch die tatsächlich verwendeten Funktionen importiert werden.
⭐️ Namenskonflikte auflösen
Gegeben ist folgender Code-Ausschnitt:
from text_tools import analyse
from math_tools import analyse
resultat_textanalyse = analyse("Das ist ein Beispielsatz.")
resultat_math_analyse = analyse("3 + 5 * 2 - 8 / 4")
Wir importieren hier aus den zwei Modulen text_tools und math_tools je eine Funktion, die zufällig in beiden Modulen analyse() heisst. Das kann durchaus passieren, denn verschiedene Module können unabhängig voneinander von verschiedenen Presonen entwickelt werden.
Das ist aber ein Problem: Woher weiss Python, welche der beiden Funktionen wir jeweils meinen, wenn wir analyse() aufrufen?
Um solche Namenskonflikte zu vermeiden, können wir beim Importieren einen Alias vergeben. Ein Alias ist ein alternativer Name, den wir einem Modul oder einer Funktion während des Imports geben können. Dazu verwenden wir das Schlüsselwort as:
from text_tools import analyse as text_analyse
from math_tools import analyse as math_analyse
resultat_textanalyse = text_analyse("Das ist ein Beispielsatz.")
resultat_math_analyse = math_analyse("3 + 5 * 2 - 8 / 4")
Damit ist das Problem gelöst, denn jetzt sagen wir Python:
- Importiere die
analyse()-Funktion aus demtext_tools-Modul und nenne sie hiertext_analyse. - Importiere die
analyse()-Funktion aus demmath_tools-Modul und nenne sie hiermath_analyse.
Der Alias-Name kann beliebig gewählt werden, solange er den Namenskonventionen für Variablen entspricht.
In unsere Python-Datei haben wir somit nun gar keine analyse()-Funktion mehr, sondern nur noch text_analyse() und math_analyse(), die jetzt eindeutig benannt sind.
Wichtig zu wissen: Dieser Alias gilt nur in der Datei, in der er definiert wurde. In den beiden ursprünglichen Modulen text_tools und math_tools heissen die Funktionen weiterhin analyse() und werden in anderen Python-Datein somit auch weiterhin mit from text_tools import analyse bzw. from math_tools import analyse importiert.