Das Erstellen von Modulen in Python
Anlegen einer Skriptdatei
Wir legen nun die folgende Skriptdatei »util.py« (mit dem „Vornamen“ »util« und dem „Nachnamen“ »py«) im Verzeichnis des Hauptpgrogrammes an.
util.py
lichtgeschwindigkeit = 299_792_458
print( 'alpha', __name__ )
(»util.py« ist der Dateiname. Die Datei enthält zwei Zeilen: »lichtgeschwindigkeit = 299_792_458« und »print( 'alpha', __name__ )«.)
IDLE Bei Verwendung von IDLE können die beiden Zeilen in das Editorfenster geschrieben werden, und die Datei kann dann unter dem Namen »util.py« abgespeichert werden. Normalerweise ist das richtige Verzeichnis bei einem neu gestartetem IDLE bereits voreingestellt.
Wenn das Skript nun einfach auf die gewohnte Weise gestartet wird (etwas mit „Run Module“ unter IDLE oder mit dem Kommando »python3 util.py«), dann sollte folgende Ausgabe erscheinen:
- Protokoll
alpha __main__
Importieren der Skriptdatei
Durch einen Import als Modul (ohne die Endung »py«) können Quelldateien ausgeführt werden, die sich im aktuellen Verzeichnis befinden.
Solch ein Skript kann auch als ein Modul angesehen und importiert werden.
Zum Importieren wird der Vorname des Skripts hinter »import« angegeben.
Beim Importieren wird das Skript ausgeführt und der angegebene Name an das importierte Modul gebunden.
- Protokoll
import util
alpha util
Ausführen der Skriptdatei
Wenn man dieselbe Datei in IDLE lädt und direkt ausführt, lautet der Name des Moduls »__main__«.
- Ausgabe
alpha __main__
Die Bedeutung von »name«
Der Wert des Namens »__name__« ist das Modul, in dem er ausgewertet wird. Wenn ein Skript als Modul importiert wird und sich »__name__« in diesem Skript befindet und während der Ausführung des Importierens ausgewertet wird, ist dies der Vorname des Skripts, in dem sich »__name__« befindet. Falls »__name__« direkt im Hauptprogramm (und nicht in einem importierten Modul) ausgeführt wird, hat es den Wert »__main__«.
- Protokoll (bei direkter Ausführung von »print( __name__ )« ohne Verwendung von »import«)
print( __name__ )
__main__
- Protokoll (bei Ausführung von »print( __name__ )« durch Import eines diese Anweisung enthaltenden Skriptes namens »util«)
print( __name__ )
util
Importieren von Namen
Nach einer entsprechenden Importanweisung können in einem Modul definierte Namen verwendet werden.
- Protokoll (übersetzt und überarbeitet)
print( lichtgeschwindigkeit )
Namensfehler: Der Name 'lichtgeschwindigkeit' wurde nicht definiert.
from util import lichtgeschwindigkeit
print( lichtgeschwindigkeit )
2
Under -Namen
Mit einem Grundstrich beginnende Namen werden nicht durch »import *« importiert.
util.py
a = 1
b = 2
_c = 3main.py
from util import *
print( a )
print( b )
print( _c )Protokoll
1
2
NameError: name '_c' is not defined
Beschränkung des Gültigkeitsbereichs
Durch das Auslagern der beiden Funktionen »do_plus« und »do_minus« in ein separates Modul wird ganz deutlich gemacht, daß die Variable »_size« nur zu diesen beiden Funktionen gehört, denn andere Funktionen können jetzt nicht ohne weiteres auf diese Variable zugreifen und sie nicht verändern.
turtle_size.py
from turtle import *
_size = 1
def do_plus():
"""Vergroessern der Stiftbreite"""
global _size
_size += 1
pensize( _size )
def do_minus():
"""Verkleinern der Stiftbreite"""
global _size
_size -= 1 -( _size == 0 )
pensize( _size )main.py
from turtle import *
from winsound import Beep
from turtle_size import *
speed( False )def do_right():
"""Bewegung nach vorne und Drehung nach rechts"""
Beep( 1000, 100 )
forward( 50 )
right( 60 )
def do_left():
"""Bewegung nach vorne und Drehung nach links"""
Beep( 2000, 100 )
forward( 50 )
left( 60 )
onkey( do_right, 'Right' )
onkey( do_left, 'Left' )
onkey( do_plus, 'plus' )
onkey( do_minus, 'minus' )
onkey( lambda: Beep( 200, 100 ), ' ' )
listen()mainloop() # Unter manchen Python-Implementationen noetig
Importe und Änderungen ⃗
module.py
i = 1
def increment_i():
global i
i += 1
def print_i():
print( f"{i = } in module" )main.py
from module import *
print_i()
print( f"{i = } in main" )increment_i()
print_i()
print( f"{i = } in main" )i = i + 1
print_i()
print( f"{i = } in main" )- Protokoll
i = 1 in module
i = 1 in main
i = 2 in module
i = 1 in main
i = 2 in module
i = 2 in main
Wie man sieht, ist es nicht ohne weiteres möglich von außen auf die Variablen eines Moduls zuzugreifen.
Beim Import wird nur einmal deren Wert kopiert, aber es wird eine neue Variable im Hauptprogramm angelegt, auch wenn sie denselben Namen wie die Modulvariable aus dem Modul »module« hat.
Importe aus bestimmten Verzeichnissen ⃗
Ein relativer Import aus einem Unterverzeichnis ist möglich, so kann mit »import a.b« oder »from a import b« ein Modul »b« aus dem Unterverzeichnis »a« (relativ zum Orte des importierenden Skripts) importiert werden. Jedoch ist dies eigentlich für die Verwendung in regelrechten Paketen vorgesehen (Pakete wurden in diesem Kurs bisher noch nicht behandelt). Daher erlaubt es keinen Import aus Oberverzeichnissen.
Die beste Lösung zum Import eines Moduls aus einem bestimmten Verzeichnis ist es oft, dieses Modul in ein Paket zu packen und das Paket dann regelrecht zu installieren. Wie das geht, wurde aber in diesem Kurs bisher noch nicht behandelt.
Für Anfänger ist es daher zunächst eine praktische Lösung, alle Python -Skripte und Python -Module in einem einzigen Verzeichnis zu sammeln.
Ermittlung des aktuellen Verzeichnisses ⃗
Nach »from os import getcwd« ist der Wert einer Auswertung von »getcwd()« der Pfadname eines Verzeichnisses, das wir hier auch als aktuelles Verzeichnis bezeichnen. Es handelt sich um das aktuelle Verzeichnis der »getcwd()« auswertenden Python-Implementation.
- Protokoll
from os import getcwd
print( getcwd() )
C:\Users\example\Python37
Die hier gezeigte Ausgabe ist nur ein Beispiel ! Das aktuelle Verzeichnis kann sich im Laufe der Zeit verändern (daher die Bezeichnung „aktuell“). Es wird in verschiedenen Fällen herangezogen, in denen ein Verzeichnis benötigt wird.
Erneutes Ausführen ⃗
Beim einem erneuten Importieren eines schon einmal importierten Skriptes geschieht nichts (bis zum Neustart der Python -Implementation).
- Protokoll
import util
Daher ist die import-Anweisung nicht allgemein zum Starten eines Moduls als Programm brauchbar. (Weil man das Programm dann nach einer Änderung nicht auf einfache Weise neu starten kann.)
Es ist zwar möglich, Module erneut zu importieren, jedoch enthält dies soviel Komplikationen, daß es nach der Veränderung eines Moduls am einfachsten ist, die Python -Implementation neu zu starten und das Modul dann erneut zu importieren.
Wir können jetzt also Module anlegen, in denen wir Namen bestimmte Werte zuweisen können. Durch eine import-Anweisung können wir diese Namen verwenden.
Das erneute Importieren kann jedoch durch »reload« veranlaßt werden.
- Protokoll
from imp import reload
reload( util )
Danach ist ein eventuelles »from util import …« zu wiederholen, um eventuell aktualisierte Definitionen erneut einzulesen.
Festlegen des Rückgabecodes ⃗
Die Wertwirkfunktion »system« ermöglicht es, Windows -Kommandos auszuführen, die ihr beim Aufruf als Argument vom Typ »str« übergeben werden.
Wenn das Windows -Kommando »cmd« mit »system« aufgerufen wird, startet der Windows -Interpretierer »cmd« gleich im richtigen Verzeichnis (dem Python -Verzeichnis).
- Protokoll (Python -Implementation)
from os import system
system( "cmd" )
Nun können Windows-Kommandos eingegeben werden.
Wir erstellen und starten ein Skript mit dem Rückgabecode 0.
- Protokoll (Windows -Interpretierer im Python -Verzeichnis)
Microsoft Windows
echo from sys import exit>tmp.py
echo exit( 0 )>>tmp.py
tmp.py
Der Rückgabecode kann von Windows verwendet werden.
- Protokoll (Windows -Interpretierer im Python -Verzeichnis)
echo %ERRORLEVEL%
0
Wir erstellen und starten ein Skript mit dem Rückgabecode 1.
- Protokoll (Windows -Interpretierer im Python -Verzeichnis)
echo from sys import exit>tmp.py
echo exit( 1 )>>tmp.py
tmp.py
Der Rückgabecode kann von Windows verwendet werden.
- Protokoll (Windows -Interpretierer im Python -Verzeichnis)
echo %ERRORLEVEL%
1
Wir kehren wieder zur Python -Implementation zurück.
- Protokoll (Windows -Interpretierer im Python -Verzeichnis)
exit
- Protokoll (Python -Implementation)
1
Umlenken der Ein- und Ausgabe ⃗
Durch das Umlenken der Eingabe kann die Eingabe für ein Python -Programm aus einer Datei kommen und/oder in eine Datei geschrieben werden.
- Protokoll (Python -Implementation)
from os import system
system( "cmd" )
- Protokoll (Windows -Interpretierer im Python -Verzeichnis)
echo 2+3>tmp.txt
echo print(eval(input()))>tmp.py
tmp.py <tmp.txt >out.txt
type out.txt
5
- Protokoll (Windows -Interpretierer im Python -Verzeichnis)
exit
- Protokoll (Python -Implementation)
0