|I l@ve RuBoard|
Interaction. Assuming your Python is configured properly, you should participate in an interaction that looks something like this:
% python copyright information lines... >>> "Hello World!" 'Hello World!' >>> # <Ctrl-D or Ctrl-Z to exit>
Programs. Here's what your code (i.e., module) file and shell interactions should look like:
% cat module1.py print 'Hello module world!' % python module1.py Hello module world!
Modules. The following interaction listing illustrates running a module file by importing it. Remember that you need to reload it to run again without stopping and restarting the interpreter. The bit about moving the file to a different directory and importing it again is a trick question: if Python generates a module1.pyc file in the original directory, it uses that when you import the module, even if the source code file (.py) has been moved to a directory not on Python's search path. The .pyc file is written automatically if Python has access to the source file's directory and contains the compiled bytecode version of a module. We look at how this works in more detail in Chapter 5.
% python >>> import module1 Hello module world! >>>
Scripts. Assuming your platform supports the #! trick, your solution will look like the following (though your #! line may need to list another path on your machine):
% cat module1.py #!/usr/local/bin/python (or #!/usr/bin/env python) print 'Hello module world!' % chmod +x module1.py % module1.py Hello module world!
Errors. The interaction below demonstrates the sort of error messages you get if you complete this exercise. Really, you're triggering Python exceptions; the default exception handling behavior terminates the running Python program and prints an error message and stack trace on the screen. The stack trace shows where you were at in a program when the exception occurred (it's not very interesting here, since the exceptions occur at the top level of the interactive prompt; no function calls were in progress). In Chapter 7, you will see you can catch exceptions using try statements and process them arbitrarily; you'll also see that Python includes a full-blown source-code debugger for special error detection requirements. For now, notice that Python gives meaningful messages when programming errors occur (instead of crashing silently):
% python >>> 1 / 0 Traceback (innermost last): File "<stdin>", line 1, in ? ZeroDivisionError: integer division or modulo >>> >>> x Traceback (innermost last): File "<stdin>", line 1, in ? NameError: x
Breaks. When you type this code:
L = [1, 2] L.append(L)
you create a cyclic data-structure in Python. In Python releases before Version 1.5.1, the Python printer wasn't smart enough to detect cycles in objects, and it would print an unending stream of [1, 2, [1, 2, [1, 2, [1, 2, and so on, until you hit the break key combination on your machine (which, technically, raises a keyboard-interrupt exception that prints a default message at the top level unless you intercept it in a program). Beginning with Python Version 1.5.1, the printer is clever enough to detect cycles and prints [[...]] instead.
The reason for the cycle is subtle and requires information you'll gain in Chapter 2. But in short, assignment in Python always generates references to objects (which you can think of as implicitly followed pointers). When you run the first assignment above, the name L becomes a named reference to a two-item list object. Now, Python lists are really arrays of object references, with an append method that changes the array in-place by tacking on another object reference. Here, the append call adds a reference to the front of L at the end of L, which leads to the cycle illustrated in Figure C.1. Believe it or not, cyclic data structures can sometimes be useful (but not when printed!).
|I l@ve RuBoard|