Learning Python - Mark Lutz [478]
As a rule of thumb, be as specific in your handlers as you can be—empty except clauses and Exception catchers are handy, but potentially error-prone. In the last example, for instance, you would be better off saying except KeyError: to make your intentions explicit and avoid intercepting unrelated events. In simpler scripts, the potential for problems might not be significant enough to outweigh the convenience of a catchall, but in general, general handlers are generally trouble.
Catching Too Little: Use Class-Based Categories
On the other hand, neither should handlers be too specific. When you list specific exceptions in a try, you catch only what you actually list. This isn’t necessarily a bad thing, but if a system evolves to raise other exceptions in the future, you may need to go back and add them to exception lists elsewhere in your code.
We saw this phenomenon at work in the prior chapter. For instance, the following handler is written to treat MyExcept1 and MyExcept2 as normal cases and everything else as an error. Therefore, if you add a MyExcept3 in the future, it will be processed as an error unless you update the exception list:
try:
...
except (MyExcept1, MyExcept2): # Breaks if you add a MyExcept3
... # Non-errors
else:
... # Assumed to be an error
Luckily, careful use of the class-based exceptions we discussed in Chapter 33 can make this trap go away completely. As we saw, if you catch a general superclass, you can add and raise more specific subclasses in the future without having to extend except clause lists manually—the superclass becomes an extendible exceptions category:
try:
...
except SuccessCategoryName: # OK if I add a myerror3 subclass
... # Non-errors
else:
... # Assumed to be an error
In other words, a little design goes a long way. The moral of the story is to be careful to be neither too general nor too specific in exception handlers, and to pick the granularity of your try statement wrappings wisely. Especially in larger systems, exception policies should be a part of the overall design.
* * *
[79] A related call, os._exit, also ends a program, but via an immediate termination—it skips cleanup actions and cannot be intercepted with try/except or try/finally blocks. It is usually only used in spawned child processes, a topic beyond this book’s scope. See the library manual or follow-up texts for details.
Core Language Summary
Congratulations! This concludes your look at the core Python programming language. If you’ve gotten this far, you may consider yourself an Official Python Programmer (and should feel free to add Python to your résumé the next time you dig it out). You’ve already seen just about everything there is to see in the language itself, and all in much more depth than many practicing Python programmers initially do. You’ve studied built-in types, statements, and exceptions, as well as tools used to build up larger program units (functions, modules, and classes); you’ve even explored important design issues, OOP, program architecture, and more.
The Python Toolset
From this point forward, your future Python career will largely consist of becoming proficient with the toolset available for application-level Python programming. You’ll find this to be an ongoing task. The standard library, for example, contains hundreds of modules, and the public domain offers still more tools. It’s possible to spend a decade or more seeking proficiency with all these tools, especially