stl michael poeltl © 2011,2013

Das sys-Modul

Highlights

Hier eine Auflistung mancher items, die so bequem angesprungen werden können. Werde aber sicher nicht alle 69 (python3.2.1) anführen.

Einleitung

Das sys-Modul besteht, so wie fast jedes Modul, aus Funktionen und aus simplen Namen, die eine spezielle Information mit sich tragen.
Doch zuallererst wollen wir uns einmal zeigen lassen, wieviele items das sys-Modul aktuell (python3.2.1) mitbringt:

>>> import sys
>>> print (sys)
<module 'sys' (built-in)>
>>> len(dir(sys))
73
>>>

Und ein Blick in diese Liste wird uns zeigen, dass wir schnell herausfinden können, auf welchem Betriebssysem unser Programm eingesetzt wird, oder, was ist der höchstmögliche Integerwert auf genau diesem PC, welche python-Version kommt zum Einsatz, etc.

sys.prefix

Gibt jenen Pfad bis zu jenem Verzeichnis aus, in den python installiert wurde.
/usr oder /usr/local, etc

>>> sys.prefix
'/usr/local'
>>>

Zum Beispiel könnte es ja einmal interessant sein, das Verzeichnis einer python-Installation herauszufinden. Das ginge so:

>>> print (os.path.join(sys.prefix, 'lib',
'python'+sys.version[:3]))
/usr/local/lib/python3.2
>>>

Bezüglich Versionsauskunft gibt sys.version_info noch mehr Information preis.

>>> sys.version_info
sys.version_info(major=3, minor=2, micro=2, releaselevel='final', serial=0)
>>> python3 = sys.version_info[0] == 3
>>> python3
True
>>> python2 = sys.version_info[0] == 2
>>> python2
False
>>>

sys.getdefaultencoding

>>> sys.getdefaultencoding()
'utf-8'
>>>

sys.executable

Welcher python-Interpreter am Werke ist, kann man folgendermaßen herausfinden:

>>> sys.executable
'/usr/local/bin/python3'
>>>

Kann von Nuzen sein, den Interpreter (und den Pfad zu ihm) zu kennen.

sys.platform

>>> print ("Wir sind auf {}, hoechstmoeglicher int-Wert ist {} und die python-Version ist {}".format(sys.platform, sys.maxsize, sys.version))
Wir sind auf linux2, hoechstmoeglicher int-Wert auf diesem 32-bit-System der einem Namen zugewiesen werden kann ist (2**31 -1) 2147483647 und die python-Version ist 3.2.1 (default, Jul 20 2011, 10:50:06) 
[GCC 4.5.2]
>>> if sys.platform.startswith('linux'):
...     print ("hello linux-world!")
... 
hello linux-world!
>>>

sys.path

sys.path gibt die Suchpfade aus, also jene Verzeichnispfade, die vom python-Interpreter beschritten werden sollen, um da nach Modulen zu suchen. a

>>> print (sys.path)
['', '/usr/local/lib/python32.zip', '/usr/local/lib/python3.2', '/usr/local/lib/pyt
hon3.2/plat-linux2', '/usr/local/lib/python3.2/lib-dynload', '/usr/local/lib/python
3.2/site-packages']
>>> sys.path.append('/tmp/mike')
>>> print (sys.path)
['', '/usr/local/lib/python32.zip', '/usr/local/lib/python3.2', '/usr/local/lib/pyt
hon3.2/plat-linux2', '/usr/local/lib/python3.2/lib-dynload', '/usr/local/lib/python
3.2/site-packages', '/tmp/mike']
>>>

Das/Dein PYTHONPATH-settting in Deiner .bashrc (oder sonstigem user-seitigen startsource-file wirst Du auch wiederfinden in der ausgegebenen Liste. In der Umgebungsvariable PYTHONPATH können freilich mehr als nur ein Pfad vorkommen, diese sind dann mit Doppelpunkt voneinander getrennt.

Genauso können wir uns status-Aussagen ausgeben lassen. Zum Beispiel, welche Module sind aktuell geladen. Wieviele Identifier zeigen auf ein Objkt?

sys.modules

>>> print (sys.modules)
{'reprlib': <module 'reprlib' from '/usr/local/lib/python3.2/reprlib.py'>,
'heapq': <module 'heapq' from '/usr/local/lib/python3.2/heapq.py'>,
'sre_compile': <module 'sre_compile' from '/usr/local/lib/python3.2/sre_compile.py'>, '_collections': <module '_collections' (built-in)>,
...
}
>>> print (sys.modules.keys())
dict_keys(['reprlib', 'heapq', 'sre_compile', '_collections', 'locale', '_sre',
'functools', '__main__', '_compat_pickle', 'site', '_string', 'subprocess',
'sysconfig', 'operator', ...
]
>>> sys.getrefcount(sys)
53
>>> a = 12399
>>> sys.getrefcount(a)
2
>>>

sys.getrefcount

getrefcount() gibt aus, wie oft auf ein Objekt referenziert wurde (ist also ein counter, ein Zähler für den garbage collector). Wir konnten uns auch die einzelnen Module via help() oder der python-Doku genauer unter die Lupe nehmen, und das eine oder das andere bereits autodidakt lernen.

sys hat aber noch mehr zu bieten. Zum Beispiel, der argument vectorargv.
Da wird an erster Stelle der Programmname geführt, und danach die Paramter, die man an der Kommandozeile angegeben hatte.

einen Piepton (beep) haben wir dann und wann schon 'mal unseren Rechner tuten hören. Wie kann man das bewusst in python machen?
Einfach mit der Escape-Sequenz \\a.

>>> print( '\a' )

>>>

Den Piepton kann ich nicht aufschreiben, aber du kannst mir glauben, es hat beep gemacht. Kleiner Schöheitsfehler vielleicht ist die leerzeile.
Wie könnt man das verhindern?
Zum Einen, indem man den default-Zeilenumbruch verhindert, und zum anderen, indem man sys.stdout einsetzt. Hier noch beide Beispiele:

>>> print('\a',end='')
>>> import sys
>>> sys.stdout.write('\a')
1
>>>
>>> cat bep/argv_sys.py
#! /usr/bin/env python3

import sys

def main():
    print ("Das\n{}\n ist Pfad+pythonscript und danach die mitgegebenen params".format(sys.argv))

if __name__ == '__main__':
    main()
user@host:~> python3 bsp/argv_sys.py margret michelle chenny
Das
['bsp/argv_sys.py', 'margret', 'michelle', 'chenny']
 ist Pfad+pythonscript und danach die mitgegebenen params
>>>

Oder sehen wir uns ein python-Programm an, das zuerst sehr komplex aussieht, sich aber bei genauerer Betrachtung als harmlos einfach zu lesen und zu verstehen

user@host:~> cat bsp/more.py
#! /usr/bin/env python3

#  aus dem buch "Programming Python" von mark Lutz
#+ 3rd ed. p. 95

def more(text, numlines=15):
    lines = text.split('\n')
    while lines:
        chunk = lines[:numlines]
        lines = lines[numlines:]
        for line in chunk: print (line)
        if lines and input('more? ') not in ['y', 'Y']: break

if __name__ == '__main__':
    import sys
    more(open(sys.argv[1]).read(), 20)
user@host:~> python3 bsp/more.py /etc/services
...

sys.stdin, sys.stdout, sys.stderr

>>> for stream in (sys.stdin, sys.stdout, sys.stderr): print (stream)
... 
<_io.TextIOWrapper name='' mode='r' encoding='UTF-8'>
<_io.TextIOWrapper name='' mode='w' encoding='UTF-8'>
<_io.TextIOWrapper name='' mode='w' encoding='UTF-8'>
>>>

Hier geht es zum Seitenanfang und