Online Book Reader

Home Category

Learning Python - Mark Lutz [475]

By Root 1642 0
file objects are automatically closed when garbage collected if still open, it’s sometimes difficult to be sure when that will occur.

The most general and explicit way to guarantee termination actions for a specific block of code is the try/finally statement:

myfile = open(r'C:\misc\script', 'w')

try:

...process myfile...

finally:

myfile.close()

As we saw in Chapter 33, some objects make this easier in Python 2.6 and 3.0 by providing context managers run by the with/as statement that terminate or close the objects for us automatically:

with open(r'C:\misc\script', 'w') as myfile:

...process myfile...

So which option is better here? As usual, it depends on your programs. Compared to the try/finally, context managers are more implicit, which runs contrary to Python’s general design philosophy. Context managers are also arguably less general—they are available only for select objects, and writing user-defined context managers to handle general termination requirements is more complex than coding a try/finally.

On the other hand, using existing context managers requires less code than using try/finally, as shown by the preceding examples. Moreover, the context manager protocol supports entry actions in addition to exit actions. Although the try/finally is perhaps the more widely applicable technique, context managers may be more appropriate where they are already available, or where their extra complexity is warranted.

Debugging with Outer try Statements

You can also make use of exception handlers to replace Python’s default top-level exception-handling behavior. By wrapping an entire program (or a call to it) in an outer try in your top-level code, you can catch any exception that may occur while your program runs, thereby subverting the default program termination.

In the following, the empty except clause catches any uncaught exception raised while the program runs. To get hold of the actual exception that occurred, fetch the sys.exc_info function call result from the built-in sys module; it returns a tuple whose first two items contain the current exception’s class and the instance object raised (more on sys.exc_info in a moment):

try:

...run program...

except: # All uncaught exceptions come here

import sys

print('uncaught!', sys.exc_info()[0], sys.exc_info()[1])

This structure is commonly used during development, to keep programs active even after errors occur—it allows you to run additional tests without having to restart. It’s also used when testing other program code, as described in the next section.

Running In-Process Tests

You might combine some of the coding patterns we’ve just looked at in a test-driver application that tests other code within the same process:

import sys

log = open('testlog', 'a')

from testapi import moreTests, runNextTest, testName

def testdriver():

while moreTests():

try:

runNextTest()

except:

print('FAILED', testName(), sys.exc_info()[:2], file=log)

else:

print('PASSED', testName(), file=log)

testdriver()

The testdriver function here cycles through a series of test calls (the module testapi is left abstract in this example). Because an uncaught exception in a test case would normally kill this test driver, you need to wrap test case calls in a try if you want to continue the testing process after a test fails. The empty except catches any uncaught exception generated by a test case as usual, and it uses sys.exc_info to log the exception to a file. The else clause is run when no exception occurs—the test success case.

Such boilerplate code is typical of systems that test functions, modules, and classes by running them in the same process as the test driver. In practice, however, testing can be much more sophisticated than this. For instance, to test external programs, you could instead check status codes or outputs generated by program-launching tools such as os.system and os.popen, covered in the standard library manual (such tools do not generally raise exceptions for errors in the external programs—in fact, the test cases may run

Return Main Page Previous Page Next Page

®Online Book Reader