Section 3.3. Introducing the sys Module


3.3. Introducing the sys Module

On to module details; as mentioned earlier, the sys and os modules form the core of much of Python's system-related tool set. Let's now take a quick, interactive tour through some of the tools in these two modules before applying them in bigger examples. We'll start with sys, the smaller of the two; remember that to see a full list of all the attributes in sys, you need to pass it to the dir function (or see where we did so earlier in this chapter).

3.3.1. Platforms and Versions

Like most modules, sys includes both informational names and functions that take action. For instance, its attributes give us the name of the underlying operating system on which the platform code is running, the largest possible integer on this machine, and the version number of the Python interpreter running our code:

 C:\...\PP3E\System>python >>> import sys >>> sys.platform, sys.maxint, sys.version ('win32', 2147483647, '2.4 (#60, Nov 30 2004, 11:49:19) [MSC v.1310 32 bit (Intel)]') >>> >>> if sys.platform[:3] == 'win': print 'hello windows' ... hello windows 

If you have code that must act differently on different machines, simply test the sys.platform string as done here; although most of Python is cross-platform, nonportable tools are usually wrapped in if tests like the one here. For instance, we'll see later that today's program launch and low-level console interaction tools vary per platformsimply test sys.platform to pick the right tool for the machine on which your script is running.

3.3.2. The Module Search Path

The sys module also lets us inspect the module search path both interactively and within a Python program. sys.path is a list of strings representing the true search path in a running Python interpreter. When a module is imported, Python scans this list from left to right, searching for the module's file on each directory named in the list. Because of that, this is the place to look to verify that your search path is really set as intended.[*]

[*] It's not impossible that Python sees PYTHONPATH differently than you do. A syntax error in your system shell configuration files may botch the setting of PYTHONPATH, even if it looks fine to you. On Windows, for example, if a space appears around the = of a DOS set command in your autoexec.bat file (e.g., set NAME = VALUE), you will actually set NAME to an empty string, not to VALUE!

The sys.path list is simply initialized from your PYTHONPATH settingthe content of any .pth path files located in Python's directories on your machine plus system defaultswhen the interpreter is first started up. In fact, if you inspect sys.path interactively, you'll notice quite a few directories that are not on your PYTHONPATHsys.path also includes an indicator for the script's home directory (an empty stringsomething I'll explain in more detail after we meet os.getcwd) and a set of standard library directories that may vary per installation:

 >>> sys.path  ['', 'C:\\PP3rdEd\\Examples',  ...plus standard paths deleted... ] 

Surprisingly, sys.path can actually be changed by a program, too. A script can use list operations such as append, del, and the like to configure the search path at runtime to include all the source directories to which it needs access. Python always uses the current sys.path setting to import, no matter what you've changed it to:

 >>> sys.path.append(r'C:\mydir')  >>> sys.path  ['', 'C:\\PP3rdEd\\Examples',  ...more deleted..., 'C:\\mydir'] 

Changing sys.path directly like this is an alternative to setting your PYTHONPATH shell variable, but not a very good one. Changes to sys.path are retained only until the Python process ends, and they must be remade every time you start a new Python program or session. However, some types of programs (e.g., scripts that run on a web server) may not be able to depend on PYTHONPATH settings; such scripts can instead configure sys.path on startup to include all the directories from which they will need to import modules.

Windows Directory Paths

Because backslashes normally introduce escape code sequences in Python strings, Windows users should be sure to either double up on backslashes when using them in DOS directory path strings (e.g., in "C:\\dir", \\ is an escape sequence that really means \), or use raw string constants to retain backslashes literally (e.g., r"C:\dir").

If you inspect directory paths on Windows (as in the sys.path interaction listing), Python prints double \\ to mean a single \. Technically, you can get away with a single \ in a string if it is followed by a character Python does not recognize as the rest of an escape sequence, but doubles and raw strings are usually easier than memorizing escape code tables.

Also note that most Python library calls accept either forward (/) or backward (\) slashes as directory path separators, regardless of the underlying platform. That is, / usually works on Windows too and aids in making scripts portable to Unix. Tools in the os and os.path modules, described later in this chapter, further aid in script path portability.


3.3.3. The Loaded Modules Table

The sys module also contains hooks into the interpreter; sys.modules, for example, is a dictionary containing one name:module entry for every module imported in your Python session or program (really, in the calling Python process):

 >>> sys.modules {'os.path': <module 'ntpath' from 'C:\Program Files\Python\Lib\ntpath.pyc'>,... >>> sys.modules.keys( ) ['os.path', 'os', 'exceptions', '_ _main_ _', 'ntpath', 'strop', 'nt', 'sys', '_ _builtin_ _', 'site', 'signal', 'UserDict', 'string', 'stat'] >>> sys <module 'sys' (built-in)> >>> sys.modules['sys'] <module 'sys' (built-in)> 

We might use such a hook to write programs that display or otherwise process all the modules loaded by a program (just iterate over the keys list of sys.modules). sys also exports tools for getting an object's reference count used by Python's garbage collector (getrefcount), checking which modules are built into this Python (builtin_module_names), and more.

3.3.4. Exception Details

Some of the sys module's attributes allow us to fetch all the information related to the most recently raised Python exception. This is handy if we want to process exceptions in a more generic fashion. For instance, the sys.exc_info function returns the latest exception's type, value, and traceback object:

 >>> try: ...     raise IndexError ... except: ...     print sys.exc_info( ) ... (<class exceptions.IndexError at 7698d0>, <exceptions.IndexError instance at 797140>, <traceback object at 7971a0>) 

We might use such information to format our own error message to display in a GUI pop-up window or HTML web page (recall that by default, uncaught exceptions terminate programs with a Python error display). The first two items returned by this call have reasonable string displays when printed directly, and the third is a traceback object that can be processed with the standard traceback module:

 >>> import traceback, sys >>> def grail(x): ...     raise TypeError, 'already got one' ... >>> try: ...     grail('arthur') ... except: ...     exc_info = sys.exc_info( ) ...     print exc_info[0] ...     print exc_info[1] ...     traceback.print_tb(exc_info[2]) ... exceptions.TypeError already got one   File "<stdin>", line 2, in ?   File "<stdin>", line 2, in grail 

The TRaceback module can also format messages as strings and route them to specific file objects; see the Python library manual for more details.

I should make two portability notes. First, the most recent exception type, value, and traceback objects are also available via other names:

 >>> try: ...     raise TypeError, "Bad Thing" ... except: ...     print sys.exc_type, sys.exc_value ... exceptions.TypeError Bad Thing 

But these names represent a single, global exception, and they are not specific to a particular thread (threads are covered in Chapter 5). If you mean to raise and catch exceptions in multiple threads, exc_info provides thread-specific exception details. In fact, you are better off using exc_info in all cases today, as the older tools are now documented as deprecated and may be removed in a future version of Python.

It has also been suggested (in the 2.4 library reference manual and the Python 3.0 PEP document) that string-based exceptions may be removed in a future Python release. This seems more radical and less certain. But if you want to avoid potential future work, use class-based exceptions instead. Because they allow you to define categories of exceptions, they are better than strings in terms of code maintenance anyhow; by listing categories, your exception handlers are immune to future changes. Built-in exceptions have been classes since Python 1.5.


3.3.5. Other sys Module Exports

The sys module exports additional tools that we will meet in the context of larger topics and examples introduced later in this chapter and book. For instance:

  • Command-line arguments show up as a list of strings called sys.argv.

  • Standard streams are available as sys.stdin, sys.stdout, and sys.stderr.

  • Program exit can be forced with sys.exit calls.

Since all of these lead us to bigger topics, though, we will cover them in sections of their own.




Programming Python
Programming Python
ISBN: 0596009259
EAN: 2147483647
Year: 2004
Pages: 270
Authors: Mark Lutz

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net