What's New in Python 2.5by Jeff Cogswell
It's hard to believe Python is more than 15 years old already. While that may seem old for a programming language, in the case of Python it means the language is mature. In spite of its age, the newest versions of Python are powerful, providing everything you would expect from a modern programming language.
This article provides a rundown of the new and important features of Python 2.5. I assume that you're familiar with Python and aren't looking for an introductory tutorial, although in some cases I do introduce some of the material, such as generators.
Changes and Enhancements to the Language Itself
Python 2.5 includes many useful improvements to the language. None of the changes are huge; nor do they require changes to your existing 2.4 code.
Other languages, particularly C and C++, have for years allowed conditional expressions, which are expressions that include an
if statement. The idea is simple: You have a variable, and you want to set the variable to one value if some condition is true; otherwise, you want to set the variable to another variable.
Certainly, you could always do this in Python using a block if statement like so:
if x > 15: a = 1 else: a = 2
Many programmers prefer shortcuts, however. The C language introduced the idea of doing the same assignment on a single line:
a = x > 15 ? 1 : 2;
In the C code, if the condition
x > 15 evaluates to true, the expression evaluates to 1. Otherwise it evaluates to 2.
Python 2.5 now has a similar feature. The Python form is rearranged a bit:
a = 1 if x > 15 else 2
Although conditional expressions exist in other languages such as the statically typed C and C++, Python's type system is different. While exploring this new feature, I was curious if I could modify types in the middle of the construct. Here goes:
a = "abc" if x > 15 else 10
This ran just fine. Of course, it's probably not the safest code in terms of introducing bugs, but you can use different types if you have a compelling reason to do so.
Slight Changes to Exception Handling for the Long Term
Python 2.5 includes changes to the
Exception class hierarchy. In general, the changes are mostly transitional changes in preparation for Python 3.0, with certain pre-2.5 features having been deprecated. That means you can still use the previous features, but the language will discourage you from doing so, as they will no longer work once Python 3.0 eventually arrives.
One newly-deprecated feature is the use of raising strings as exceptions. Previously (I used Python 2.4.3), you could write code such as:
>>> raise "Invalid argument" Traceback (most recent call last): File "<stdin>", line 1, in ? Invalid argument >>>
With Python 2.5, you can still raise strings as exceptions, but you also get a deprecation warning:
>>> raise "Invalid argument" __main__:1: DeprecationWarning: raising a string exception is deprecated Traceback (most recent call last): File "<stdin>", line 1, in <module> Invalid argument >>>
However, you only get the warning the first time per Python session. Subsequent raises don't result in the warning. Python 2.5 encourages you to stop writing code like this, because when Python 3.0 arrives, your code will not compile.
In addition to the deprecation of raising strings as exceptions, Python 2.5 also rearranged the exception class hierarchy. The new
BaseException class is the base class for
Exception. You should now derive all your custom exception classes from
Exception, or from a class derived from
Two other exception classes,
SystemExit, also extend
BaseException, but not
Exception. Thus, you can trap your own exceptions, and then trap all other exceptions derived from
Exception. This will trap every exception except
SystemExit. Why would you not want to trap those two exceptions? That way your program will end when the user presses Ctrl+C without you having to manually catch and respond to Ctrl+C, or without you having to manually skip catching Ctrl+C to let the system handle it. The same is true with the
SystemExit exception, which should force the program to stop.
This particular new feature, then, is less of a feature and more of a requirement: Recode your exception classes to extend
Exception. Then you'll be fine when Python 3.0 arrives.
Finally, there is now another short warning about future exceptions in Python. Presently, exception classes have both a message and an args member. The general idea was that message would be a string, and args would be a list of any additional arguments to the exception. However, this is redundant, because the message member doesn't have to be a string. Thus, Python 3.0 will have no more args member, so you should stop using it.
Better Exception Handling
In addition to the changes to the hierarchy, the try mechanism has improved with Python 2.5. Previously, you could not mix
finally blocks without using two layers of exceptions. Now you can use them both in a single block, which makes life easier. The order matters, however. You must have your
try block first, then optionally your exception handlers, then optionally an
else block that runs if no exceptions occurred, and then optionally your
finally block, which runs in all cases. Here's an example:
try: test() except ZeroDivisionError: print "The expression resulted in a division-by-zero error" except Exception: print "Oops" else: print "All is good" finally: print "And everything is finished"
In previous versions, you had to use two
try blocks, with one inside the other, and the outer having the
finally block. Now you can use a single block for all of it.