python-course.eu

1. sys-Module

By Bernd Klein. Last modified: 06 Apr 2022.

Information on the Python Interpreter

Like all the other modules, the sys module has to be imported with the import statement, i.e.

import sys

If there are questions about the import statement, we recommend the introductory chapter of our basic course concerning this topic Modular Programming and Modules

The sys module provides information about constants, functions and methods of the Python interpreter. dir(system) gives a summary of the available constants, functions and methods. Another possibility is the help() function. Using help(sys) provides valuable detail information.

The module sys informs e.g. about the maximal recursion depth (sys.getrecursionlimit() ) and provides the possibility to change (sys.setrecursionlimit())

sys module and system programming

The current version number of Python can be accessed as well. We show this in the following Python session:

$ python
Python 3.8.5 (default, Sep  4 2020, 07:30:14) 
[GCC 7.3.0] :: Anaconda, Inc. on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.version
'3.8.5 (default, Sep  4 2020, 07:30:14) \n[GCC 7.3.0]'
>>> sys.version_info
sys.version_info(major=3, minor=8, micro=5, releaselevel='final', serial=0)
>>> 

Command-line arguments

Lots of scripts need access to the arguments passed to the script, when the script was started. argvargv (or to be precise sys.argv) is a list, which contains the command-line arguments passed to the script. The first item of this list contains the name of the script itself. The arguments follow the script name.

The following script iterates over the sys.argv list :

import sys

# list of arguments:
print(sys.argv)

# or it can be iterated via a for loop:

for i in range(len(sys.argv)):
    if i == 0:
        print("Function name: ", sys.argv[0])
    else:
        print(f"{i:1d}. argument: {sys.argv[i]}")

We save this script as arguments_test.py. If we call it, we get the following output::

$ python arguments_test.py  a b c d e
['arguments_test.py', 'a', 'b', 'c', 'd', 'e']
Function name:  arguments_test.py
1. argument: a
2. argument: b
3. argument: c
4. argument: d
5. argument: e

Changing the output behaviour of the interactive Python shell

Python's interactive mode is one of the things which make Python special among other programming languages like Perl or Java. As we have seen in the chapter Interactive mode of our introductory tutorial, it's enough to write an expression on the command line and get back a meaningful output. However some users might prefer a different output behaviour. To change the way the interpreter prints interactively entered expressions, you will have to rebind sys.displayhook to a callable object.

We will demonstrate this in the following interactive example session:

>>> import sys
>>> s = "cheese"
>>> s
'cheese'
>>> def my_display(x):
...     print("out: ", x)
... 
>>> sys.displayhook = my_display
>>> s
out:  cheese

Standard data streams

standard data streams

Every serious user of a UNIX or Linux operating system knows standard streams, i.e. input, standard output and standard error. They are known as pipes. They are commonly abbreviated as stdin, stdout, stderr.

The standard input (stdin) is normally connected to the keyboard, while the standard error and standard output go to the terminal (or window) in which you are working.

These data streams can be accessed from Python via the objects of the sys module with the same names, i.e. sys.stdin, sys.stdout and sys.stderr.

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

The following example illustrates the usage of the standard data streams:

>>> import sys
>>> print("Using the stdout stream")
Using the stdout stream
>>> sys.stdout.write("Another way to do it!\n")
Another way to do it!
22
>>> x = input("read value via stdin: ")
read value via stdin: Whatever you do
>>> print("Your input: "); sys.stdin.readline().rstrip()
Your input: 
Whatever you do
'Whatever you do'
>>> 

The following example combines input and output:

import sys

while True:
    # output to stdout:
    print("Yet another iteration ...")
    try:
        # reading from sys.stdin (stop with Ctrl-D):
        number = int(input("Enter a number: "))
        if number == 0:
          print("0 has no inverse", file=sys.stderr)
        else:
          print(f"inverse of {number} is {1.0/number}") 
    except (ValueError, EOFError):
        # empty string or non int value stops loop
        print("\nciao")
        break

If we save the previous example under "streams.py" and use a file called "number.txt" with numbers (one number per line) for the input, we can call the script in the following way from the Bash shell:

$ python streams.py < numbers.txt

The numbers.txt file contains the following content:

45
23
554
0
1

It returns the following results:

Yet another iteration ...
Enter a number: inverse of 45 is 0.022222222222222223
Yet another iteration ...
Enter a number: inverse of 23 is 0.043478260869565216
Yet another iteration ...
Enter a number: inverse of 554 is 0.0018050541516245488
Yet another iteration ...
Enter a number: 0 has no inverse
Yet another iteration ...
Enter a number: inverse of 1 is 1.0
Yet another iteration ...
Enter a number: 
ciao

It's also possible to redirect the output into a file:

$ python streams.py < numbers.txt > output.txt

Now the only output left in the shell will be:

0 has no inverse

because this comes via the sterr stream.

Redirections

Umleitungen

There is hardly a user of a Linux or a Unix Shell, e.g. the Bourne or the Bash Shell, who hasn't used input or output redirections. It's not exaggerated to say that a useful work is not possible without redirections.

The standard output (stdout) can be redirected e.g. into a file, so that we can process this file later with another program. The same is possible with the standard error stream, we can redirect it into a file as well. We can redirect both stderr and stdout into the same file or into separate files.

The following script should be self-explanatory. But nevertheless here are some explanations: The first statement uses the regular standard output (stdout), i.e. the text "Coming through stdout" will be printed into the terminal from which the script has been called. In the next line we are storing the standard output channel in the variable save_stdout, so that we will be capable of restoring the original state at a later point in the script. After this we open a file "test.txt" for writing. After the statement sys.stdout = fh all print statements will directly print into this file. The original condition is restored with sys.stdout = save_stdout.

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()

The following example shows how to redirect the standard error stream into a file:

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()

The file `errors.txt` will contain the following content after the execution of the program above:

Traceback (most recent call last):
  File "redi.py", line 7, in 
    x = 10 / 0
ZeroDivisionError: division by zero

It's possible to write into the error stream directly, i.e. without changing the general output behaviour. This can be achieved by appending >> sys.stderr to a print statement.

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()

Other interesting Variables and Constants in the sys Module

Name Description
byteorder An indicator of the native byte order.
The following output was created on a Linux machine and Python 2.6.5:
>>> sys.byteorder
'little'
>>> 
The value will be 'big' on big-endian (most-significant byte first) platforms, and 'little' on little-endian (least-significant byte first) platforms.
executable A string containing the name of the executable binary (path and executable file name) for the Python interpreter. E.g. "c:\\Python31\\python.exe on Windows 7 or "/usr/bin/python" on Linux.
>>> sys.executable
'/usr/bin/python'
maxsize The largest positive integer supported by the platform's Py_ssize_t type, and thus the maximum size lists, strings, dicts, and many other containers can have.
>>> sys.maxsize
9223372036854775807
maxunicode An integer giving the largest supported code point for a Unicode character. The value of this depends on the configuration option that specifies whether Unicode characters are stored as UCS-2 or UCS-4.
>>> sys.maxunicode
1114111
modules The value of sys.modules is a dictionary mapping the names of modules to modules which have already been loaded. This can be manipulated e.g. to enforce the reloading of modules. Note that removing a module from this dictionary is not the same as calling reload() on the corresponding module object.
path Contains the search pyth, where Python is looking for modules.
>>> sys.path
['', '/home/bernd/anaconda3/lib/python38.zip', '/home/bernd/anaconda3/lib/python3.8', '/home/bernd/anaconda3/lib/python3.8/lib-dynload', '/home/bernd/anaconda3/lib/python3.8/site-packages', '/home/bernd/anaconda3/lib/python3.8/site-packages/python_ly-0.9.7-py3.8.egg']
>>> 
platform Name of the platform on which Python is running, e.g. "linux2" for Linux and "win32" for Windows
>>> sys.platform
'linux'
>>> 
version Version number of the Python interpreter
>>> sys.version
'3.8.5 (default, Sep  4 2020, 07:30:14) \n[GCC 7.3.0]'
>>> 
version_info Similar information than sys.version, but the output is a tuple containing the five components of the version number: major, minor, micro, release-level, and serial. The values of this tuple are integers except the value for the release level, which is one of the following: 'alpha', 'beta', 'candidate', or 'final'.
>>> sys.version_info
sys.version_info(major=3, minor=8, micro=5, releaselevel='final', serial=0)
>>> 
getsizeof Return the size of object in bytes.
>>> x = 5
>>> sys.getsizeof(x)
28
>>> s = "hello"
>>> sys.getsizeof(s)
54
__stdin__
__stdout__
__stderr__
These attributes contain the original values of stdin, stderr and stdout at the start of the program. They can be useful to print to the actual standard stream no matter if the sys.std* object has been redirected. They can also be used to restore the actual files to known working file objects in case they have been overwritten with a broken object. But instead of using these values, the original stream should always be explicitly saved in a variable (as shown in our previous examples) before replacing it, and the original state should be restored by using the saved object.
getrecursionlimit()
setrecursionlimit(limit)
getrecursionlimit() returns the current value of the recursion limit, the maximum depth of the Python interpreter stack. This limit prevents infinite recursion from causing an overflow of the C stack and crashing Python.
>>> sys.getrecursionlimit()
>>> 1000

setrecursionlimit(limit) sets the maximum depth of the Python interpreter stack to the value of "limit".

Live Python training

instructor-led training course

Enjoying this page? We offer live Python training courses covering the content of this site.

See: Live Python courses overview

Enrol here