29.2 Zugriff auf die Laufzeitumgebung – sys
Das Modul sys der Standardbibliothek stellt vordefinierte Variablen und Funktionen zur Verfügung, die sich auf den Python-Interpreter selbst beziehen oder eng mit diesem zusammenhängen. So können Sie über das Modul sys beispielsweise die Versionsnummer des Interpreters oder des Betriebssystems abfragen. Das Modul stellt dem Programmierer eine Reihe von Informationen zur Verfügung, die mitunter sehr nützlich sein können.
Um die Beispiele dieses Abschnitts ausführen zu können, muss zuvor das Modul sys eingebunden werden:
>>> import sys
29.2.1 Kommandozeilenparameter
Die Liste sys.argv enthält die Kommandozeilenparameter, mit denen das Python-Programm aufgerufen wurde. argv[0] ist der Name des Programms selbst. Im interaktiven Modus ist argv leer. Bei dem beispielhaften Programmaufruf
programm.py -bla 0 -blubb abc
referenziert argv die folgende Liste:
['programm.py', '-bla', '0', '-blubb', 'abc']
Verwenden Sie das Modul argparse, wenn Sie Kommandozeilenparameter komfortabel verwalten möchten (vgl. Kapitel 30, »Kommandozeilenparameter«).
29.2.2 Standardpfade
Die Liste path enthält Pfade, die beim Einbinden eines Moduls der Reihe nach vom Interpreter durchsucht werden. Das zuerst gefundene Modul mit dem gesuchten Namen wird eingebunden.
Es steht dem Programmierer frei, die Liste so zu modifizieren, dass das Einbinden eines Moduls nach seinen Wünschen erfolgt.
29.2.3 Standard-Ein-/Ausgabeströme
Das Modul sys enthält Referenzen auf die Standard-Ein-/Ausgabeströme des Systems. Das sind die Dateiobjekte, die für Ein- und Ausgaben des Interpreters verwendet werden. Dabei bezeichnet sys.stdin (für Standard Input) das Dateiobjekt, aus dem die Benutzereingaben beim Aufruf von input gelesen werden. In das Dateiobjekt sys.stdout (Standard Output) werden alle Ausgaben des Python-Programms geschrieben, während Ausgaben des Interpreters, beispielsweise Tracebacks, in sys. stderr (Standard Error) geschrieben werden.
Das Überschreiben dieser vorbelegten Dateiobjekte mit eigenen Dateiobjekten erlaubt es, Ein- und Ausgaben auf andere Streams, beispielsweise in eine Datei, umzulenken. Beachten Sie dabei, dass sys.stdin stets ein vollwertiges Dateiobjekt sein muss, während für sys.stdout und sys.stderr eine Instanz reicht, die eine Methode write implementiert.
Die ursprünglichen Streams von sys.stdin, sys.stdout und sys.stderr werden in sys.__stdin__, sys.__stdout__ und sys.__stderr__ gespeichert, sodass sie wiederhergestellt werden können.
29.2.4 Das Programm beenden
Die Funktion exit des Moduls sys wirft eine SystemExit-Exception. Diese hat, sofern sie nicht abgefangen wird, zur Folge, dass das Programm ohne Traceback-Ausgabe beendet wird.
>>> sys.exit()
Optional können Sie eine ganze Zahl übergeben, die als Exit Code ans Betriebssystem übergeben wird. Ein Exit Code von 0 steht im Allgemeinen für ein erfolgreiches Beenden des Programms, und ein Exit Code ungleich 0 repräsentiert einen Programmabbruch aufgrund eines Fehlers.
>>> sys.exit(1)
Wenn Sie eine andere Instanz übergeben haben, beispielsweise einen String, wird diese nach stderr ausgegeben, bevor das Programm mit dem Exit Code 0 beendet wird.
>>> sys.exit("Fehler")
Fehler
29.2.5 Details zur Python-Version
Das benannte Tupel sys.implementation stellt Informationen über den laufenden Python-Interpreter bereit. Neben den auch individuell bereitgestellten Einträgen hexversion und version_info enthält das Tupel mit dem Eintrag name den Namen des Interpreters, beispielsweise "cpython" für die Standardimplementierung.
>>> sys.implementation
namespace(_multiarch='x86_64-linux-gnu', cache_tag='cpython-36',
hexversion=50725104, name='cpython', version=sys.version_info(major=3,
minor=6, micro=0, releaselevel='final', serial=0))
Die beiden Komponenten version und hexversion von sys.implementation können auch gesondert über sys.version_info bzw. sys.hexversion abgerufen werden:
>>> sys.version_info
sys.version_info(major=3, minor=6, micro=0, releaselevel='final', serial=0)
>>> hex(sys.hexversion)
'0x30600f0'
Die Konstante sys.hexversion enthält die Versionsnummer des Python-Interpreters als ganze Zahl. Wenn sie wie im oben dargestellten Beispiel, ausgeführt unter Python 3.6.0, durch Aufruf der Built-in Function hex als Hexadezimalzahl geschrieben wird, wird der Aufbau der Zahl deutlich. Es ist garantiert, dass hexversion mit jeder Python-Version größer wird, dass Sie also mit den Operatoren < und > testen können, ob die verwendete Version des Interpreters aktueller ist als eine bestimmte, die für die Ausführung des Programms mindestens vorausgesetzt wird.
Schließlich können Sie über den String sys.executable den vollständigen Pfad zum aktuell laufenden Python-Interpreter herausfinden.
29.2.6 Details zum Betriebssystem
Der String sys.platform enthält eine Kennung des laufenden Betriebssystems. Die Kennungen der drei gängigsten Betriebssysteme können Sie Tabelle 29.1 entnehmen.
System | Kennung |
---|---|
Linux | "linux" |
macOS | "darwin" |
Windows | "win32" |
[»] Hinweis
Bis Python 3.2 war der Wert von platform unter Linux "linux2" bzw. "linux3", abhängig von der Linux-Version. Ab Python 3.3 ist der Wert unter Linux durchweg "linux".
Aus diesem Grund ist es ratsam, mittels
sys.platform.startswith("linux")
zu prüfen, ob das Programm auf einem Linux-System ausgeführt wird.
Unter Windows-Systemen existiert die Funktion sys.getwindowsversion, die Details über die Version des aktuell verwendeten Windows-Betriebssystems zurückgibt:
>>> sys.getwindowsversion()
sys.getwindowsversion(major=10, minor=0, build= 14393, platform=2,
service_pack='')
Die Funktion gibt ein benanntes Tupel zurück, dessen erste drei Elemente ganze Zahlen sind und die Versionsnummer beschreiben. Das vierte Element ist ebenfalls eine ganze Zahl und steht für die verwendete Plattform. Folgende Werte sind hier gültig:
Plattform | Bedeutung |
---|---|
0 | Windows 3.1 (32 Bit) |
1 | Windows 95/98/ME |
2 | Windows NT/2000/XP/Server 2003/Vista/Server 2008/7/8/10 |
3 | Windows CE |
Das letzte Element des Tupels ist ein String, der weiterführende Informationen enthält.
Um zwischen den einzelnen Windows-Versionen zu unterscheiden, die unter Plattform 2 zusammengefasst sind, können Sie die Versionsnummer (bestehend aus dem major- und dem minor-Feld des Tupels) heranziehen:
Name | Major | Minor |
---|---|---|
Windows 2000 | 5 | 0 |
Windows XP | 5 | 1 |
Windows Server 2003 | 5 | 2 |
Windows Vista bzw. Windows Server 2008 | 6 | 0 |
Windows 7 | 6 | 1 |
Windows 8 | 6 | 2 |
Windows 10 | 10 | 0 |
Unter anderen Betriebssystemen als Microsoft Windows ist die Funktion getwindowsversion nicht verfügbar.
Die Konstante sys.byteorder spezifiziert die Byte-Order[ 123 ](Die Byte-Order gibt an, in welcher Reihenfolge die einzelnen Bytes eines Wertes im Speicher abgelegt werden, der mehr als ein Byte belegt. Die Byte-Order ist relevant, wenn Binärdaten zwischen verschiedenen Plattformen ausgetauscht werden. Ein x86-PC ist ein Little-Endian-System. ) des aktuellen Systems. Der Wert ist entweder "big" für ein Big-Endian-System, bei dem das signifikanteste Byte an erster Stelle gespeichert wird, oder "little" für ein Little-Endian-System, bei dem das am wenigsten signifikante Byte zuerst gespeichert wird.
29.2.7 Hooks
Das Modul sys erlaubt den Zugriff auf sogenannte Hooks (dt. »Haken«). Das sind Funktionen, die bei gewissen Aktionen des Python-Interpreters aufgerufen werden. Durch Überschreiben dieser Funktionen kann sich der Programmierer in den Interpreter »einhaken« und so die Funktionsweise des Interpreters verändern.
displayhook(value)
Diese Funktion wird immer dann aufgerufen, wenn das Ergebnis eines Ausdrucks im interaktiven Modus ausgegeben werden soll, also beispielsweise in der folgenden Situation:
>>> 42
42
Durch Überschreiben von displayhook mit einer eigenen Funktion lässt sich dieses Verhalten ändern. Im folgenden Beispiel möchten wir erreichen, dass bei einem eingegebenen Ausdruck nicht das Ergebnis selbst, sondern die Identität des Ausdrucks ausgegeben wird:
>>> def f(value):
... print(id(value))
...
>>> sys.displayhook = f
>>> 42
139716935035616
>>> 97 + 32
139716935038400
>>> "Hallo Welt"
139716901939824
Beachten Sie, dass displayhook nicht aufgerufen wird, wenn eine Ausgabe mittels print erfolgt:[ 124 ](Das wäre auch sehr ungünstig, da wir im Hook selbst ja eine print-Ausgabe vornehmen. Riefe eine print-Ausgabe wieder den Hook auf, befänden wir uns in einer endlosen Rekursion. )
>>> print("Hallo Welt")
Hallo Welt
Das ursprüngliche Funktionsobjekt von displayhook können Sie über sys.__displayhook__ erreichen und somit die ursprüngliche Funktionsweise wiederherstellen:
>>> sys.displayhook = sys.__displayhook__
excepthook(type, value, traceback)
Diese Funktion wird immer dann aufgerufen, wenn eine nicht abgefangene Exception auftritt. Sie ist dafür verantwortlich, den Traceback auszugeben. Durch Überschreiben dieser Funktion mit einem eigenen Funktionsobjekt lassen sich zum Beispiel Fehler protokollieren oder die Ausgabe eines Tracebacks verändern.
Der Funktion excepthook werden beim Aufruf der Exception-Typ, der Exception-Wert (üblicherweise die Fehlermeldung) und ein sogenanntes Traceback-Objekt übergeben, das Informationen über die Stelle enthält, an der die Exception geworfen wurde.
Im folgenden Beispiel richten wir einen Hook ein, um bei einer nicht abgefangenen Exception keinen drögen Traceback mehr zu erhalten, sondern einen hämischer Kommentar:
>>> def f(type, value, traceback):
... print('gnahahaha: "{}"'.format(value))
...
>>> sys.excepthook = f
>>> abc
gnahahaha: "name 'abc' is not defined"
Das ursprüngliche Funktionsobjekt von excepthook können Sie über sys.__excepthook__ erreichen und so die ursprüngliche Funktionsweise wiederherstellen:
>>> sys.excepthook = sys.__excepthook__