What Is New in Python 2.5
Python 2.5 was released on September 18, 2006. The most significant language addition is the with statement for resource management, the conditional expression (ternary operator), and the new functools module. Python 2.5 also introduced a more powerful try/except/finally that combined what previously required two separate blocks, and the ctypes module for calling C libraries directly.
| Category | Change | PEP / Reference |
|---|---|---|
| New Syntax | with statement and context managers |
PEP 343 |
| New Syntax | Conditional expressions: x if condition else y |
PEP 308 |
| New Syntax | try/except/finally combined in one block |
PEP 341 |
| New Modules | functools -- partial(), reduce(), wraps() |
-- |
| New Modules | ctypes -- call C shared libraries from Python |
-- |
| New Modules | cProfile -- faster drop-in for profile |
-- |
| Standard Library | __future__ imports for Python 3 compatibility features |
-- |
| Standard Library | generator send() and throw() -- enhanced generators |
PEP 342 |
| Standard Library | collections.defaultdict |
-- |
| Standard Library | Absolute imports: from __future__ import absolute_import |
PEP 328 |
Key New Features in Python 2.5
The with Statement (PEP 343)
The with statement guarantees that a resource is cleaned up after the block exits, whether normally or via an exception. This replaces the widespread try/finally pattern for file handles, locks, and database connections.
# Without with
f = open("data.txt")
try:
data = f.read()
finally:
f.close()
# With with statement
with open("data.txt") as f:
data = f.read() # f.close() is called automatically
Any object that implements __enter__ and __exit__ can be used as a context manager. The contextlib module provides helpers to create context managers from generator functions.
Conditional Expressions (PEP 308)
Python's ternary operator: value_if_true if condition else value_if_false. It was long-requested and finally added in 2.5.
label = "admin" if user.is_admin else "user"
result = x if x > 0 else -x # absolute value
Enhanced Generators: send() and throw() (PEP 342)
Generators can now receive values via generator.send(value) and exceptions via generator.throw(type). The value sent becomes the result of the current yield expression. This is the machinery that enabled coroutine patterns well before async def.
def accumulator():
total = 0
while True:
value = yield total
if value is None:
break
total += value
gen = accumulator()
next(gen) # Start the generator -- yields 0
gen.send(10) # yields 10
gen.send(20) # yields 30
collections.defaultdict
defaultdict is a dict subclass that calls a factory function to provide default values for missing keys, eliminating the if key not in d: d[key] = [] boilerplate.
from collections import defaultdict
groups = defaultdict(list)
for item, group in data:
groups[group].append(item) # No KeyError on first access
FAQ
What is the difference between contextlib.contextmanager and a class-based context manager?
Both work the same way externally. A class with __enter__ and __exit__ is more explicit and reusable. @contextmanager wraps a generator in a context manager automatically -- useful for one-off managers and simpler setups where writing a full class is overkill.
Is functools.partial() better than a lambda?
For most cases, partial is cleaner. It is picklable (lambdas generally are not), has a useful repr, and performance is similar. Use partial when you're partially applying a function and will pass it as a callback.
Can ctypes call functions in any shared library?
Any C-compatible shared library (.so on Linux, .dll on Windows, .dylib on macOS) that exports C calling conventions. C++ name-mangling makes C++ libraries harder to call -- prefer a C wrapper. ctypes also allows direct memory manipulation, which is powerful but dangerous if used incorrectly.
What happened to try/except/finally before Python 2.5?
In Python 2.4 and earlier, you could not combine except and finally in the same try block. You had to nest them: try: try: ... except ...: ... finally: .... Python 2.5 merged the two into a single unified try/except/else/finally structure.
Is cProfile a drop-in replacement for profile?
Yes, the API is identical. cProfile is implemented in C and has much lower overhead than the Python-based profile module. For most profiling tasks, prefer cProfile: python -m cProfile -s cumtime your_script.py.