exec in Python (exec in Python), Lektion, Seite 724057
https://www.purl.org/stefan_ram/pub/exec_python (Permalink) ist die kanonische URI dieser Seite.
Stefan Ram
Python-Kurs

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 = 3
main.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

Seiteninformationen und Impressum   |   Mitteilungsformular  |   "ram@zedat.fu-berlin.de" (ohne die Anführungszeichen) ist die Netzpostadresse von Stefan Ram.   |   Eine Verbindung zur Stefan-Ram-Startseite befindet sich oben auf dieser Seite hinter dem Text "Stefan Ram".)  |   Der Urheber dieses Textes ist Stefan Ram. Alle Rechte sind vorbehalten. Diese Seite ist eine Veröffentlichung von Stefan Ram. Schlüsselwörter zu dieser Seite/relevant keywords describing this page: Stefan Ram Berlin slrprd slrprd stefanramberlin spellched stefanram724057 stefan_ram:724057 exec in Python Stefan Ram, Berlin, and, or, near, uni, online, slrprd, slrprdqxx, slrprddoc, slrprd724057, slrprddef724057, PbclevtugFgrsnaEnz Erklärung, Beschreibung, Info, Information, Hinweis,

Der Urheber dieses Textes ist Stefan Ram. Alle Rechte sind vorbehalten. Diese Seite ist eine Veröffentlichung von Stefan Ram.
https://www.purl.org/stefan_ram/pub/exec_python