Keeping Up with Python: the 2.2 Release

Python 2.2 resolves some well known deficiencies of the language and introduces some new powerful constructs that are key strengths of other object-oriented languages.

Python 2.2 made its debut at the end of
2001, and its first bug-fix version 2.2.1 was recently released
from the core developers at PythonLabs. The 2.2.x family is full of
new features and capabilities, some considered significant
additions and improvements to the language. These updates give
Python developers a significant boost in terms of flexibility.

Python is a simple yet robust language combining the ease of
scripting tools with the application-building power of compiled
object-oriented programming languages. With Jython, the
Java-compiled edition of the Python interpreter, Java programmers
are discovering a tool that raises their productivity and
development speed to a new level.

You can stay up-to-speed on these changes by reading the PEPs
(Python Enhancement Proposals), which are created to give any
reasonable idea an ear from the Python community. Before
consideration is made for any update to the language, the problems
and proposed solutions are presented along with the rationale for,
and details behind, the change. Not only can you get the exact
details on a PEP at the web site (see Resources), but you can also
find out the status of a PEP. After reaching a consensus, a subset
of PEPs is approved and slated for each release. For example, the
changes in 2.2 (meaning the entire 2.2.x set of releases) consist
primarily of five major PEPs: 234, 238, 252, 253 and 255.

For starters, 2.2 begins the process of unifying Python
integers and long integers. Integer calculations can no longer
raise overflow errors because they will automatically be cast into
longs if the value overflows. Statically nested scopes, introduced
in 2.1 and now standard, free Python from its restrictive two-scope
model (see PEP 227). Previously, one had to put from
__future__ import nested_scopes at the start of the
script to enable nested scopes. Now that directive is no longer
necessary as it has become standard. Unicode support has also been
upgraded for UCS-4 (32-bit unsigned integers; see PEP 261). Minor
updates to the Python Standard Library include a new e-mail
package, a new XML-RPC module, the ability to add IPv6 support to
the socket module and the new hot-shot profiler (PEP).

The most significant changes and additions to 2.2 are
iterators and generators, changing the division operator and
unifying types and classes.

Iterators

Iterators give the programmer the ability to traverse or
“iterate through” elements of a data set. They are especially
useful when the items of such sets are of differing types. Python
has already simplified part of this programming process, as its
sequence data types (lists, strings, tuples) are already
heterogenous, and iterating through them is as simple as a “for”
loop without having to create any special mechanism.

The new iteration support in Python works seamlessly with
Python sequences but now also allows programmers to iterate through
nonsequence types, including user-defined objects. An additional
benefit is the improvement of iteration through other Python
types.

Now, that all sounds good, but why iterators in Python? In
particular, PEP 234 cites that the enhancement will:

Provide an extensible iterator interface.

Bring performance enhancements to list
iteration.

Allow for big performance improvements in
dictionary iteration.

Allow for the creation of a true iteration
interface as opposed to overriding methods originally meant for
random element access.

Be backward-compatible with all existing
user-defined classes and extension objects that emulate sequences
and mappings.

Result in more concise and readable code that
iterates over nonsequence collections (mappings and files for
instance).

Iterators can be created directly by using the new iter()
built-in function or implicitly for objects that come with their
own iteration interface. For example, lists have a built-in
iteration interface, so “for eachItem in myList” will not change
at all.

Calling iter(obj) returns an iterator for that type of
object. An iterator has a single method, next(), that returns the
next item in the set. A new exception, StopIteration, signals the
end of the set.

Iterators do have restrictions, however. You can't move
backward, go back to the beginning or copy an iterator. If you want
to iterate over the same objects again (or simultaneously), you
have to create another iterator object.

Sequences

As mentioned before, iterating through Python sequence types
is as expected:

There is also another form of the iter() built-in function,
iter(callable, sentinel), which returns an iterator as before. The
difference is that each call to the iterator's next() method will
invoke callable() to obtain successive values and raise
StopIteration when the value sentinel is returned.