I l@ve RuBoard Previous Section Next Section

1.13 The sys Module

The sys module provides a number of functions and variables that can be used to manipulate different parts of the Python runtime environment.

1.13.1 Working with Command-line Arguments

The argv list contains the arguments that were passed to the script, when the interpreter was started, as shown in Example 1-66. The first item contains the name of the script itself.

Example 1-66. Using the sys Module to Get Script Arguments
File: sys-argv-example-1.py

import sys

print "script name is", sys.argv[0]

if len(sys.argv) > 1:
    print "there are", len(sys.argv)-1, "arguments:"
    for arg in sys.argv[1:]:
        print arg
else:
    print "there are no arguments!"

script name is sys-argv-example-1.py
there are no arguments!

If you read the script from standard input (like "python < sys-argv-example-1.py"), the script name is set to an empty string. If you pass in the program as a string (using the -c option), the script name is set to "-c."

1.13.2 Working with Modules

The path list contains a list of directory names in which Python looks for extension modules (Python source modules, compiled modules, or binary extensions). When you start Python, this list is initialized from a mixture of built-in rules, the contents of the PYTHONPATH environment variable, and the registry contents (on Windows). But since it's an ordinary list, you can also manipulate it from within the program, as Example 1-67 shows.

Example 1-67. Using the sys Module to Manipulate the Module Search Path
File: sys-path-example-1.py

import sys

print "path has", len(sys.path), "members"

# add the sample directory to the path
sys.path.insert(0, "samples")
import sample

# nuke the path
sys.path = []
import random # oops!

path has 7 members
this is the sample module!
Traceback (innermost last):
  File "sys-path-example-1.py", line 11, in ?
    import random # oops!
ImportError: No module named random

Example 1-68 demonstrates the builtin_module_names list, which contains the names of all modules built into the Python interpreter.

Example 1-68. Using the sys Module to Find Built-in Modules
File: sys-builtin-module-names-example-1.py

import sys

def dump(module):
    print module, "=>",
    if module in sys.builtin_module_names:
        print "<BUILTIN>"
    else:
        module = _ _import_ _(module)
        print module._ _file_ _

dump("os")
dump("sys")
dump("string")
dump("strop")
dump("zlib")

os => C:\python\lib\os.pyc
sys => <BUILTIN>
string => C:\python\lib\string.pyc
strop => <BUILTIN>
zlib => C:\python\zlib.pyd

The modules dictionary contains all loaded modules. The import statement checks this dictionary before it actually loads something from disk.

As you can see from Example 1-69, Python loads quite a bunch of modules before handing control over to your script.

Example 1-69. Using the sys Module to Find Imported Modules
File: sys-modules-example-1.py

import sys

print sys.modules.keys()

['os.path', 'os', 'exceptions', '_ _main_ _', 'ntpath', 'strop', 'nt',
'sys', '_ _builtin_ _', 'site', 'signal', 'UserDict', 'string', 'stat']

1.13.3 Working with Reference Counts

The getrefcount function (shown in Example 1-70) returns the reference count for a given object�that is, the number of places where this variable is used. Python keeps track of this value, and when it drops to 0, the object is destroyed.

Example 1-70. Using the sys Module to Find the Reference Count
File: sys-getrefcount-example-1.py

import sys

variable = 1234

print sys.getrefcount(0)
print sys.getrefcount(variable)
print sys.getrefcount(None)

50
3
192

Note that this value is always larger than the actual count, since the function itself hangs on to the object while determining the value.

1.13.4 Checking the Host Platform

Example 1-71 shows the platform variable, which contains the name of the host platform.

Example 1-71. Using the sys Module to Find the Current Platform
File: sys-platform-example-1.py

import sys

#
# emulate "import os.path" (sort of)...

if sys.platform == "win32":
    import ntpath
    pathmodule = ntpath
elif sys.platform == "mac":
    import macpath
    pathmodule = macpath
else:
    # assume it's a posix platform
    import posixpath
    pathmodule = posixpath

print pathmodule

Typical platform names are win32 for Windows 9X/NT and mac for Macintosh. For Unix systems, the platform name is usually derived from the output of the "uname -r" command, such as irix6, linux2, or sunos5 (Solaris).

1.13.5 Tracing the Program

The setprofiler function allows you to install a profiling function. This is called every time a function or method is called, at every return (explicit or implied), and for each exception. Let's look at Example 1-72.

Example 1-72. Using the sys Module to Install a Profiler Function
File: sys-setprofiler-example-1.py

import sys

def test(n):
    j = 0
    for i in range(n):
        j = j + i
    return n

def profiler(frame, event, arg):
    print event, frame.f_code.co_name, frame.f_lineno, "->", arg

# profiler is activated on the next call, return, or exception
sys.setprofile(profiler)

# profile this function call
test(1)

# disable profiler
sys.setprofile(None)

# don't profile this call
test(2)

call test 3 -> None
return test 7 -> 1

The profile module provides a complete profiler framework, based on this function.

The settrace function in Example 1-73 is similar, but the trace function is called for each new line:

Example 1-73. Using the sys Module to Install a trace Function
File: sys-settrace-example-1.py

import sys

def test(n):
    j = 0
    for i in range(n):
        j = j + i
    return n

def tracer(frame, event, arg):
    print event, frame.f_code.co_name, frame.f_lineno, "->", arg
    return tracer

# tracer is activated on the next call, return, or exception
sys.settrace(tracer)

# trace this function call
test(1)

# disable tracing
sys.settrace(None)

# don't trace this call
test(2)

call test 3 -> None
line test 3 -> None
line test 4 -> None
line test 5 -> None
line test 5 -> None
line test 6 -> None
line test 5 -> None
line test 7 -> None
return test 7 -> 1

The pdb module provides a complete debugger framework, based on the tracing facilities offered by this function.

1.13.6 Working with Standard Input and Output

The stdin, stdout, and stderr variables contain stream objects corresponding to the standard I/O streams. You can access them directly if you need better control over the output than print can give you. You can also replace them, if you want to redirect output and input to some other device, or process them in some non-standard way, as shown in Example 1-74.

Example 1-74. Using the sys Module to Redirect Output
File: sys-stdout-example-1.py

import sys
import string

class Redirect:

    def _ _init_ _(self, stdout):
        self.stdout = stdout

    def write(self, s):
        self.stdout.write(string.lower(s))

# redirect standard output (including the print statement)
old_stdout = sys.stdout
sys.stdout = Redirect(sys.stdout)

print "HEJA SVERIGE",
print "FRISKT HUM\303\226R"

# restore standard output
sys.stdout = old_stdout

print "M\303\205\303\205\303\205\303\205L!"

heja sverige friskt hum\303\266r
M\303\205\303\205\303\205\303\205L!

An object that implements the write method is all it takes to redirect output.

(Unless it's a C type instance, that is: Python uses an integer attribute called softspace to control spacing, and adds it to the object if it isn't there. You don't have to bother if you're using Python objects, but if you need to redirect to a C type, you should make sure that type supports the softspace attribute.)

1.13.7 Exiting the Program

When you reach the end of the main program, the interpreter is automatically terminated. If you need to exit in midflight, you can call the sys.exit function, which takes an optional integer value that is returned to the calling program. It is demonstrated in Example 1-75.

Example 1-75. Using the sys Module to Exit the Program
File: sys-exit-example-1.py

import sys

print "hello"

sys.exit(1)

print "there"

hello

It may not be obvious, but sys.exit doesn't exit at once. Instead, it raises a SystemExit exception. This means that you can trap calls to sys.exit in your main program, as Example 1-76 shows.

Example 1-76. Catching the sys.exit Call
File: sys-exit-example-2.py

import sys

print "hello"

try:
    sys.exit(1)
except SystemExit:
    pass

print "there"

hello
there

If you want to clean things up after yourself, you can install an "exit handler," which is a function that is automatically called on the way out. This is shown in Example 1-77.

Example 1-77. Catching the sys.exit Call Another Way
File: sys-exitfunc-example-1.py

import sys

def exitfunc():
    print "world"

sys.exitfunc = exitfunc

print "hello"
sys.exit(1)
print "there" # never printed

hello
world

In Python 2.0, you can use the atexit module to register more than one exit handler.

    I l@ve RuBoard Previous Section Next Section