sys-Modul

Informationen über den Python-Interpreter

sys Modul und System-Programmierung Wie alle Module muss auch das Modul sys mittels der import-Anweisung eingebunden werden, also

import sys

Bei generellen Fragen zu Modulen empfehlen wir unser einführendes Kapitel über Module und Modularisierung.

Das sys-Modul stellt Informationen in Konstanten, Funktionen und Methoden über den Python-Interpreter zur Verfügung. Einen Überblick über die verfügbaren Konstanten und Funktionen kann man sich mittels dir(sys) verschaffen. Wie auch in anderen Modulen liefert die help-Funktion, also help(sys), im Interpreter wertvolle Detailinformationen.

Das Modul sys gibt beispielsweise Auskunft über die maximale Rekursionstiefe (sys.getrecursionlimit()) und erlaubt es einem auch diese anzupassen (sys.setrecursionlimit()). Außerdem kann man die aktuelle Version von Python, - also diejenige in der das Skript oder der Interpreter ausgeführt wird - erfragen:

>>> import sys
>>> sys.version
'2.6.5 (r265:79063, Apr 16 2010, 13:57:41) \n[GCC 4.4.3]'
>>> sys.version_info
(2, 6, 5, 'final', 0)
>>> 

Kommandozeilenargumente

In vielen Anwendungen wird auf sys zugegriffen, wenn man in einem Skript auf die Kommandozeilenargumente zugreifen will oder den Namen des Skriptes erfragen will.
sys.argv ist eine Liste mit dem Funktionsnamen als erstem Element, gefolgt von den Argumenten in der Reihenfolge, in der sie auf der Kommandozeile aufgeführt worden sind. Das folgende Beispielskript zeigt, wie man argv bearbeiten kann:
#!/usr/bin/python

import sys

print sys.argv

print "oder mit for-Schleife:"

for i in range(len(sys.argv)):
    if i == 0:
        print "Funktionsname: %s" % sys.argv[0]
    else:
        print "%d. Argument: %s" % (i,sys.argv[i])
Speichert man das Skript unter arguments.py ab und ruft es auf, so erhält man folgende Ausgabe:
$ python arguments.py arg1 arg2
['arguments.py', 'arg1', 'arg2']
oder mit for-Schleife:
Funktionsname: arguments.py
1. Argument: arg1
2. Argument: arg2
$

Änderung des Ausgabeverhaltens im interaktiven Modus

Im interaktiven Modus hat man, wie im Kapitel "Der Interpreter" gezeigt, die Möglichkeit, Ausdrücke und Variablen direkt, d.h. ohne print, auszugeben. Dieses Ausgabeverhalten lässt sich ändern, indem man sys.displayhook einen neuen Wert zuweist, wie im folgenden Beispiel gezeigt:
>>> import sys
>>> x = 42
>>> x
42
>>> import sys
>>> def my_display(x):
...     print "out: ",
...     print x
... 
>>> sys.displayhook = my_display
>>> x
out:  42
>>> 
>>> print x
42

Wie man im obigen Beispiel auch sieht, ändert sich durch den neuen displayhook nicht das Ausgabeverhalten der print()-Funktion.

Standard-Datenströme

Standard-Datenströme Die Standard-Datenströme (englisch: standard streams) in Unix bzw. Linux entsprechen drei Datenströme für die Ein- und Ausgabe. Viele Linux- und Shell-Kommandos verwenden automatisch die Standardein- bzw. Standardausgabe, sobald keine Dateien in der Kommandozeile für die Ein- oder Ausgabe angegeben worden sind.
Als Standardeingabe gilt normalerweise die Tastatur. Die meisten Shell-Programme schreiben ihre Ausgaben in die Standardausgabe, d.h. das Terminalfenster oder die Textkonsole. Fehlermeldungen werden in die Standard-Fehlerausgabe ausgegeben, was üblicherweise auch dem aktuellen Terminalfenster oder der Textkonsole entspricht.

In Python gibt es die Möglichkeit auf die Standardkanäle, also stdin, stdout und stderr, zuzugreifen. Dies geschieht über die gleichlautenden Objekte stdin, stdout und stderr des Modules sys.
Die Standard-Streams (stdin, stdout und stderr) in Python sind per Default bereits geöffnet.
>>> import sys
>>> for i in (sys.stdin, sys.stdout, sys.stderr):
...     print(i)
... 
<open file '<stdin>', mode 'r' at 0x7f3397a2c0c0>
<open file '<stdout>', mode 'w' at 0x7f3397a2c150>
<open file '<stderr>', mode 'w' at 0x7f3397a2c1e0>
>>>
Das folgende Beispiel veranschaulicht die Benutzung der Standardkanäle:
>>> import sys
>>> print "Going via stdout"
Going via stdout
>>> sys.stdout.write("Another way to do it!\n")
Another way to do it!
>>> x = raw_input("read value via stdin: ")
read value via stdin: 42
>>> print x
42
>>> print "type in value: ", ; sys.stdin.readline()[:-1]
type in value: 42

'42'
>>> 
Das folgende Beispiel kombiniert Ein- und Ausgabe:
import sys

while True:
  # output to stdout:
  print "Yet another iteration ..."
  try:
    # reading from sys.stdin (stop with Ctrl-D):
    number = raw_input("Enter a number: ")
  except EOFError:
    print "\nciao"
    break
  else:
    number = int(number)
    if number == 0:
      print >> sys.stderr, "0 has no inverse"
    else:
      print "inverse of %d is %f" % (number, 1.0/number) 
Speichert man das vorige Beispiel unter "streams.py" ab und legt eine Datei "number.txt" mit Zahlen (eine Zahl pro Zeile) für die Eingaben an, dann kann man das Skript auch in der Shell wie folgt aufrufen:
$ python streams.py < numbers.txt
Man kann auch noch die Ausgaben in eine Datei umleiten:
$ python streams.py < numbers.txt > output.txt
In der Shell erscheint jetzt nur noch eine Ausgabe
0 has no inverse
da diese Ausgabe über stderr kommt.

Ein- und Ausgabeumleitung

Umleitungen Jeder ernsthafte Nutzer einer Linux- oder Unix-Shell, wie zum Beispiel der Bourne- oder Bash-Shell, benutzt häufig eine Ein- bzw. Ausgabeumleitung. Es ist nicht übertrieben, wenn man sagt, dass eine sinnvolle Arbeit in der Shell ohne Ein- und Ausgabeumleitungen kaum möglich wäre.

Bei der systemnahen Programmierung unter Python stellt sich auch sehr schnell die Notwendigkeit ein, dass man die Standardkanäle umleiten will bzw. muss.

So kann man beispielsweise die Standardausgabe (stdout) in eine Datei umleiten, um die Ausgaben archivieren zu können oder sie offline bearbeiten oder weiterverarbeiten zu können. Man kann sowohl die Standardausgabe (stdout) als auch die Standardfehlerausgabe (stderr) in Dateien umlenken. Entweder beide in die gleiche Datei oder jeweils in eine andere.
Das folgende Skript ist nahezu selbsterklärend. Die erste print-Anweisung geht in die normale Standardausgabe (stdout), also wird, wenn man das Skript auf der Kommandozeile aufruft, im Terminal ausgegeben. Dann speichern wir die Standardausgabe in der Variablen save_stdout. Anschließend öffnen wir eine Datei mit dem Namen "test.txt" zum Schreiben. nach der Zeile sys.stdout = fh gehen alle print-Anweisungen in diese Datei, also auch die Anweisung print("This line goes to test.txt"). Die Anweisung sys.stdout = save_stdout stellt wieder den Urzustand her.
import sys

print("Coming through stdout")

# stdout is saved
save_stdout = sys.stdout

fh = open("test.txt","w")

sys.stdout = fh
print("This line goes to test.txt")

# return to normal:
sys.stdout = save_stdout

fh.close()
Im folgenden Beispiel wird die Fehlerausgabe in eine Datei "errors.txt" umgeleitet. Die Division durch Null verursacht einen Fehler, der wegen der Umleitung in "errors.txt" ausgegeben wird.
import sys

save_stderr = sys.stderr
fh = open("errors.txt","w")
sys.stderr = fh

x = 10 / 0

# return to normal:
sys.stderr = save_stderr

fh.close()
Man kann auch direkt mittels einer print-Anweisung durch Anhängung eines >> sys.stderr in den Fehlerkanal schreiben, wie wir im nächsten Beispiel zeigen.
import sys

save_stderr = sys.stderr
fh = open("errors.txt","w")
sys.stderr = fh

print >> sys.stderr, "printing to error.txt"

# return to normal:
sys.stderr = save_stderr

fh.close()

Weitere Variablen und Konstanten im sys-Modul

Name Beschreibung
byteorder Enthält entweder den Wert "little" zur Bezeichnung eines Little-Endian-Systems oder "big" zur Bezeichnung eines Big-Endian-Systems.
executable Enthält den vollen Pfad zum Python-Interpreter.
>>> sys.executable
'/usr/bin/python'
maxint Der Wert entspricht dem größtmöglichen Wert, den eine int-Instanz annehmen kann. Dieser Wert ist systemabhängig.

Anmerkung betreffend Python 3.x: Die sys.maxint Konstante wurde mit Python 3.0 entfernt. Somit gibt es aktuell keine Limitierung für Integer-Werte.
maxunicode Die Variable enthält einen Integer-Wert, der den maximalen Unicode-Zeichencode-Wert angibt, den ein Unicode Zeichen haben kann.
Der maximale Zeichenwert in UCS-4 wird durch den maximalen Wert bestimmt, der in UTF-16 dargestellt werden kann, d.h. 1114111. Für UCS-2 gilt entsprechend 65535.
modules Enthält die Namen aller eingebundenen Module in Form eines Dictionary.
path Der Suchpfad, in dem der Interpreter Python-Module sucht.
>>> sys.path
['', '/usr/lib/python2.6', '/usr/lib/python2.6/plat-linux2', '/usr/lib/python2.6/lib-tk', 
'/usr/lib/python2.6/lib-old', '/usr/lib/python2.6/lib-dynload', '/usr/lib/python2.6/dist-packages', 
'/usr/lib/python2.6/dist-packages/PIL', '/usr/lib/python2.6/dist-packages/gst-0.10', 
'/usr/lib/pymodules/python2.6', '/usr/lib/python2.6/dist-packages/gtk-2.0', 
'/usr/lib/pymodules/python2.6/gtk-2.0', '/usr/lib/python2.6/dist-packages/wx-2.8-gtk2-unicode', 
'/usr/local/lib/python2.6/dist-packages']
>>> 
platform Name der zugrundeliegenden Betriebssystem-Plattform, z.B. "linux2" für Linux, "win32" für Windows oder "darwin" für macOS.
>>> sys.platform
'linux2'
>>> 
version Versionsnummer des Python-Interpreters
>>> sys.version
'2.6.5 (r265:79063, Apr 16 2010, 13:57:41) \n[GCC 4.4.3]'
>>> 
version_info Ein Tupel mit den Komponenten der Versionsnummer des Python-Interpreters.
>>> sys.version_info
(2, 6, 5, 'final', 0)
>>> 
__stdin__
__stdout__
__stderr__
Diese Attribute beinhalten die Original-Werte von stdin, stderr und stdout zum Start des Programms.
getrecursionlimit()
setrecursionlimit(limit)
getrecursionlimit() liefert den Wert der aktuell maximalen Rekursions-Tiefe. Dieser Wert dient als Schutz vor einer unendlichen Rekursion.
>>> sys.getrecursionlimit()
>>> 1000
setrecursionlimit(limit) verändert das Maximum der Rekursions-Tiefe für den Python-Interpreter auf den Wert aus "limit".