Login | Register   
LinkedIn
Google+
Twitter
RSS Feed
Download our iPhone app
TODAY'S HEADLINES  |   ARTICLE ARCHIVE  |   FORUMS  |   TIP BANK
Browse DevX
Sign up for e-mail newsletters from DevX


advertisement
 

A Parade of New Features Debuts in Python 2.5 : Page 2

Python 2.5 still has the smell of fresh paint but it's the perfect time to drill down on the most important new features in this comprehensive release. Read on for detailed explanations and examples of exception handling, resource management, conditional expressions, and more.


advertisement
Exception Handling
Python 2.5 streamlines the syntax for exception handling. Prior to 2.5 you couldn't have both an except clause and a finally clause for the same try block. If you wanted to catch exceptions and also to perform some cleanup code afterwards you had to create a nested try-except block inside a try-finally block. Now, you can have a combined try-except-finally block. I created a little program to demonstrate the differences. Here is the code followed by explanation:

import platform class Whoops(Exception): def __init__(self, message): Exception.__init__(self, message) def_go_24 = """def go_24(): # Throw exception here try: print 'Running Python 2.4 code' print '-'*24 try: raise Whoops('Alright, you got me!!!') except Whoops, e: print e x = Whoops ancestors = [] while x.__bases__: ancestors += [str(b) for b in x.__bases__] x = x.__bases__[0] print 'Whoops ancestors:', ','.join(ancestors) else: print 'I''m never going to get called' finally: print 'Finally!!!' print # Don't throw exception here try: try: print 'Everything is cool...' except Whoops, e: print e else: print 'else clause is here' finally: print 'Finally!!!' """ def_go_25 = """def go_25(): # Throw exception here try: print 'Running Python 2.5 code' print'-'*24 raise Whoops('Alright, you got me!!!') except Whoops, e: print e x = Whoops ancestors = [] while x.__bases__: ancestors += [str(b) for b in x.__bases__] x = x.__bases__[0] print 'Whoops ancestors:', ','.join(ancestors) else: print 'I''m never going to get called' finally: print 'Finally!!!' print # Don't throw exception here try: print 'Everything is cool...' except Whoops, e: print e else: print 'else clause is here' finally: print 'Finally!!!'""" if __name__=='__main__': v = platform.python_version() if v.startswith('2.4'): exec(def_go_24) go_24() elif v.startswith('2.5'): exec(def_go_25) go_25()

The program is designed to run under both Python 2.4.x and Python 2.5. It checks, using the platform.python_version() function, what version of Python it is running under and executes a similar exception handling code tailored to this version. Note that I had to create the exception handling code dynamically by defining the functions go_24 and go_25 in strings and use the exec() function to execute and actually define the functions. Then I call the right function. This is a roundabout method but it fulfills my desire to keep the code for both versions in a single file, but prevents Python 2.4 from throwing a syntax error when it encounters the try-except-finally block as an actual function definition in the file.



The Whoops class is a simple exception class that subclasses exceptions. Exception is shared by the Python 2.4 and 2.5 code although under the covers it is quite different in each version, as you will soon see.

The def_go_24 string contains a Python 2.4 function definition that has two test cases. Both test cases consist of nested try-finally + try-except block. In the first test case the Whoops exception is thrown and in the second no exception is thrown. In the first case the exception is caught and the code explores the hierarchy of Whoops' base classes. In Python 2.4 exceptions.Exception is a plain, old-style class. The else clause is not executed in this case. The finally clause of the external try-finally block is executed of course. Here is the output of the first test case:

Running Python 2.4 code ------------------------ Alright, you got me!!! Whoops ancestors: exceptions.Exception Finally!!!

In the second test case no exception is thrown so the else clause is executed and the external finally clause is executed too:

Everything is cool... else clause is here Finally!!!

The def_go_25 string contains Python 2.5 code, which is almost identical to the 2.4 code. The difference, of course, is in the exception handling code structure. Here there is only one combined try-except-finally block and there is no nesting. Check out the output:

Running Python 2.5 code ------------------------ Alright, you got me!!! Whoops ancestors: ,, Finally!!! Everything is cool... else clause is here Finally!!!

This is almost the same except for the ancestor list of Whoops. It looks different and it contains three classes as opposed to the single class of Python 2.4. Python 2.5 reorganized the exception classes hierarchy. exceptions.Exception is not the root exception anymore. Here is the new exception hierarchy:

object |--BaseException |-- KeyboardInterrupt |-- SystemExit |-- Exception |-- [all other built-in exceptions]

BaseException is the root of the built-in exception hierarchy and it is a new-style class (subclasses object). The KeyboardInterrupt and SystemExit are now siblings, just as the Exception and not sub-classes were in Python 2.4. The reason for this change is that in your code usually you don't want to catch these exceptions, but let them propagate all the way to the top and end the program. This led to cumbersome error handling code where people caught all exceptions but raised KeyboardInterrupt and SystemExit again to make sure they are not ignored silently. You can still raise classic classes as exceptions if you want. This enhancement is completely backward compatible.



Comment and Contribute

 

 

 

 

 


(Maximum characters: 1200). You have 1200 characters left.

 

 

Sitemap
Thanks for your registration, follow us on our social networks to keep up-to-date