Note: Please see the Recent Python Changes appendix in the 2nd edition of Programming Python (published March 2001), for a much more comprehensive and up to date list of Python language and library changes. The list below is no longer maintained.
This page lists and briefly describes major changes in Python between the time the first edition of Programming Python was published (10/96, Python 1.3), and the last update to this page (2/99, Python 1.5.2).
Most of these changes are minor, and by computer book standards this book is still fairly up to date (especially since it's more about how to really use Python, than about memorizing language details). In fact, most recent Python changes are optional additions which you can safely ignore when just starting out. Make sure you understand the core ideas presented in the book, before tackling the new additions.
On the other hand, Python is a growing system, and some of its recent changes impact sections of the book. I've grouped Python changes below into categories. Note: this list is a work in progress, and isn't necessarily complete (and may be out of date as soon as Guido releases another version), so be sure to also see the "What's New" release notes if you install a newer version of Python (or click here for more details on changes in Python 1.5).
Also note that there are a number of new documentation sources available, including two new O'Reilly books (Learning Python, and the Python Pocket Reference), as well as updated library, language, and C API documentation at Python's web site. The pocket reference book is partly intended to provide an up-to-date version of the "Mini-Reference" appendix in Programming Python.
Related pages:
Index for this page (XXX - more to come):
A handful of new features, most of which are optional, backward-compatible with earlier releases, and designed by and for Python wizards. I recommend that beginners stick to the true core language described in the book when first starting out, and postpone most of the new features listed here until they're comfortable with the basics.
Python now provides a name-mangling protocol which provides a limited sort of "private" mechanism for hiding class names (attributes). A name of the form "__X" inside a class statement is automatically changed by Python to "_Class__X", where "Class" is the name of the class being defined by the statement.
The upshot is that by prefixing such attributes with the name of the enclosing class, they are localized to that class, and will be distinct from similar names used by other classes. This isn't true "privacy" in the C++ sense--it avoids some name clashes, but class clients can still get to "__X" names if they know the class name. It's also an entirely optional feature, and a compromise for those wanting C++-style access restrictions.
With this extension, there are now 3 access rules in Python:
Exceptions may now take the form of class (and class instance) objects. The intent is to support exception categories: since an except clause will match a raised exception if it names the raised class or any of its superclasses, specifying superclasses allows try statements to catch broad categories without listing all members explicitly.
Moreover, Python's standard (built-in) exceptions are now classes (instead of strings as before), and have been organized into a shallow class hierarchy:
Due to demand, Guido implemented a new, standard way to import packages of modules, which replaces the older (experimental) "ni" package support module. Roughly, packages are directories of Python module files and other packages, and package imports are strings of dotted names (qualifications) which reflect the directory structure on your machine.
For instance, "import package.package.module" loads a module nested 2-levels
deep in packages (directories), and "from package.package import module" has a
similar effect. Unlike the older "ni", the new package support is always
available (without running special imports), and requires each package
directory to have a "__init__.py" module file. See www.python.org for
more details.
Python 1.5 added a new statement:
assert test [, value]is the same as:
if __debug__: if not test: raise AssertionError, value
but is easier on the eyes and keyboard. Assertions are mostly meant
for debugging, but can also be used to specify program constraints.
"assert" was added to the list of Python reserved words; "access" was
taken away (it's now been deprecated in earnest).
A few convenience methods were added to the built-in dictionary object
to avoid the need for manual "for" loops:
D.clear(), D.copy(), D.update(), and D.get(). The first two
empty and copy dictionaries. D1.update(D2) is equivalent to the for loop
"for k in D2.keys(): D1[k] = D2[k]". D.get(k) returns D[k] if it
exists and None (or the optional second argument) if not.
In support of regular expressions, Python now allows string constants
to be written in the form r"...\...", which works like a normal
string, except that Python leaves any backslashes (\) in the quotes alone;
they remain as literal "\" characters in the string, rather than being
interpreted as special escape codes by Python.
Python now supports complex number constants (e.g., 1+3j), and
complex arithmetic operations (normal math operators, plus a "cmath" module
with many of the "math" module's functions for complex numbers).
Objects created with code like L.append(L) are now detected and
printed specially by the interpreter. In the past, trying to print cyclic
objects caused the interpreter to loop (recursively), which led to a core
dump if you didn't kill it fast enough.
A raise statement without any exception or extra-data arguments is
now syntactically legal, and makes Python re-raise the most recently
raised uncaught exception.
Because exceptions can now be either string objects, or classes and class instances, you can now use any of the following raise statement forms (the last 3 of which are for backward compatibility with earlier releases where all built-in exceptions were strings):
raise string # matches except with same string object raise string, data # same, with optional data raise class, instance # matches except with class or its superclass raise instance # same as: raise instance.__class__, instance raise # reraise last exception raise class # same as: raise class(), and: raise class, instance raise class, arg # same as: raise class(arg) raise class, (arg,...) # same as: raise class(args...)
The new "**" binary operator computes the left operand raised to the
power of the right operand. It works much like the built-in "pow" function.
In an assignment ("=" statement, and other assignment contexts), you can
now assign any sort of sequence on the right to a list or tuple on the left
(e.g., "(A,B) = seq", "[A,B] = seq"). In the past, the sequence types had to
match.
Guido & Co. worked on optimizing the virtual machine, especially in Python
1.5. How much faster depends on what sort of test you run, of course, but
Python 1.5 has been clocked at almost twice as fast as its predecessors on the
Lib/test/pystone.py benchmark.
There have been lots of changes and additions to the libraries in the last two years. The list here is incomplete, and mostly focused on changes which impact examples and discussion in the book. Since the book isn't an exhaustive treatment of the libraries (there are hundreds of library modules), be sure to see the documentation for library modules you use if they're not described here.
The built-in dir function now reports attributes for modules, classes,
class instances, as well as built-in objects like lists, dictionaries, and
files. You don't need to use members like __methods__ (but still can).
A new regular expression module, "re", offers full-blown Perl-style
regular expression matching. The older "regex" module described in the book
is still available, and provides a simpler regular expression matching tool.
But the new "re" module provides a more powerful matching system; for instance,
it supports "non-greedy" matches, and most of Perl's special regular expression
syntax, including a variety of character classes. See the "re" module description
at the www.python.org doc page, or the Python Pocket Reference book.
The spilt and join functions in the string module were generalized
to do the same work as the original splitfields and joinfields. In
other words, you don't need to type the "fields" bit any more--just pass
in delimiter arguments to split and join.
Beginning in Python 1.5, the pickle module's unpickler (loader)
no longer calls class __init__ methods to recreate pickled class
instance objects. This means that classes no longer need to have
defaults for all constructor arguments to be used for persistent
objects. To force Python to call the __init__ method (as it did
before), classes must provide a __getinitargs__ method; see the
library manual for details.
An implementation of the pickle module in C is now a standard part
of Python. It's called "cpickle", and is reportedly many times faster
than the original pickle module.
To create a new or open an existing file in read+write
mode, pass a 'c' in argument 2 to anydbm.open. This changed
as of Python 1.5.2; passing a 'c' now does what passing no second
argument used to do (the second argument now defaults to 'r').
This does not impact shelve.open.
The title says it all: "rand" is now deprecated; use "random"
instead.
The CGI interface used in the Appendix A CGI mailto example has become "deprecated" (which means you can still use it, but the newer interface is recommended). In basic terms, the older interface looks like this:
Scripts automatically run by Python on start-up, used to tailor
the initial configuration. (XXX - more to come.)
Assigning to a key in the os.environ dictionary really updates
the corresponding environment variable in the C environment now; it
triggers a call to the C library's "putenv" routine, such that the changes
are reflected in integrated C code layers, as well as the environment of any
child processes spawned by the Python program. Moreover, the "putenv" routine
is now exposed in the os module ("os.putenv"); be sure to consider the extension
module example in chapter 2 for illustration purposes only.
The new exc_info() function in the sys module returns a tuple that
has values corresponding to the older sys.exc_type and sys.exc_value,
shown in the book. The difference is that the older names represent a
single global exception, and exc_info() is specific to the calling thread.
There is a new standard module called "operator", which provides
functions which implement most of the built-in Python expression
operators. For instance, "operator.add(X,Y)" does the same thing
as "X+Y", but because operator module exports are functions, they
are sometimes handy to use in things like "map", without having to
create a function or use a "lambda" form.
This section is a sampling of changes in Python tools and Python-related systems, as an extension to Appendix A. This is a partial and necessarily subjective list of exciting developments on the Python application fronts, and I'm positive I've missed a few; be sure to see www.python.org for others.
A new system worth noting: the "JPython" package is an alternative Python implementation, which compiles Python programs to Java Virtual Machine (JVM) bytecode, and provides hooks for integrating Python and Java programs. JPython makes Python an excellent scripting tool for Java-based Web systems. Like any radical development, it represents good news and/or bad news, depending on your point of view; in the interest of fairness, I'd like to summarize both sides here.
The good news: Because JPython compiles Python programs to Java byte codes, they can be run on any system with an installed JVM. JPython also provides additional tools for accessing Java objects and packages, including AWT. For instance, JPython allows Python programs to implement client-side applets, which may create portable AWT and Swing GUIs in standard Net browsers. JPython was also recently certified as "100% Pure Java".
So where does Python/Java integration fit in with Python's world view? In general, that's really the same as asking about Python/C++ integration. Now that Java has been around for a few years, it's generally classified as a systems language (in the same category as C and C++), not as a scripting language (which is Python's domain). Java is simply too complex to be useful for scripting work.
But as the book stresses, you often need both kinds of tools--a systems language for performance, and a scripting tool for usability. By integrating a true scripting language like Python with Java, programmers can realize all the same scripting benefits the book reports for integrating Python with C or C++.
JPython becomes more interesting when applied to web-based systems. For instance, by compiling Python to JVM code, it can be run as client-side code in any Java-aware browser, and have access to Java libraries. JPython is probably less useful outside of web-based systems (if Java has all the complexity of C++ and all the performance problems of an interpreted language, why not just use C++ for compute-intensive components?). But for systems that must run on the web, JPython provides an interesting and portable scripting option.
For a more complete and compelling argument for JPython than I can make here, read Guido's overview article about JPython, in developer.com (8/98).
The bad news: On the downside, JPython has a limited scope, isn't yet compatible with the standard C implementation of Python, and is somewhat slower due to the extra interpretation levels. For instance, JPython:
I'm being careful to present both its pros and cons here,
mostly because there have been some attempts to position JPython as
a replacement for standard Python--an arguably odd proposal which
would alienate tens of thousands of current Python users! But despite
its tradeoffs, JPython is an amazing tool for Java programmers, and merits
the attention of anyone involved with Java-based systems. For more
details, see the JPython page.
The COM interfaces in the PythonWin ports have evolved substantially
since the descriptions in Appendix A (where they were called OLE
interfaces). PythonWin and COM make Python an excellent alternative
to Visual Basic for scripting Windows applications. See
www.python.org for details.
Fredrik Lundh also now makes available Python executables for Windows
(9x/NT), with things like the Tkinter GUI interface for Windows and
cPickle preinstalled. See
www.pythonware.com
for links.
The SWIG system briefly described in chapters 2 and 15 has grown to
become a primary extension writers tool. It also incorporated something
called "shadow classes", which are equivalent to what the book describes
as "wrapper" or "stub" classes in chapter 15--Python classes which wrap
C++ interface extension modules or types, such that C++ classes look like
Python classes to Python programs. SWIG can
automatically generate C++ wrappers (both a C++ interface and a
Python wrapper class), given C++ type signature information.
A system for publishing Python objects on the Web has grown to
become a popular tool for CGI script writers and Web hackers.
See
http://www.digicool.com/releases/bobo for details.
A tool for generating correct HTML files (for Web page layout) from
Python class object trees has grown to maturity. See www.python.org
for more details.
The Pmw system provides powerful, higher-level widgets for Tkinter-based
GUIs in Python; it's worth checking out if you do any non-trivial Tkinter
work. See python.org for details.
Python now ships with a new point-and-click development interface
named IDLE. Written in Python using the Tkinter GUI library, IDLE
either comes in the source library's Tools directory, or is automatically
installed with Python itself (on Windows). IDLE offers a syntax-coloring
text editor, a graphical debugger, an object browser, and much more.
If you have a Python with Tk support enabled, and are used to more
advanced development interfaces, IDLE provides a nice feature-rich
alternative to the traditional Python command line. IDLE is still
evolving as I write this; it does not yet include support for
point-and-click GUI construction.
A variety of improvements and extensions, mostly aimed at simplifying the task of embedding Python in C programs, and supporting threads at the C API level.
All useful Python symbols are now exported in the single
"Python.h" header file; no other header files need be imported
(even when embedding--the extra parser and import headers aren't
needed).
All Python interpreter code is now packaged in a single library
file when you make Python. For instance, under Python 1.5, you need
only link in "libpython1.5.a" when embedding Python (instead of the
older 4 libraries plus .o's scheme). See file "Demo/embed/Makefile"
in the Python1.5 source distribution for an example.
All exposed Python symbols now start with a "Py" prefix.
For instance, "eval_input"/"file_input" parser mode constants for
embedding code strings have been renamed to Py_eval_input and
Py_file_input. Similarly, the "getprogramname" function which
optionally appears in embedding examples is now called
Py_GetProgramName, though you can instead call
Py_SetProgramName(name). When in doubt, grep for old symbols
in the Include directory of the source distribution.
A handful of new API tools provide better support for threads when embedding Python. For instance, there are tools for finalizing Python (Py_Finalize), and creating "multiple interpreters" (Py_NewInterpreter).
In many cases, multiple namespaces are sufficient to isolate names used in independent system components (and easier to manage than multiple interpreters and threads). But in some threaded programs, it's also useful to have one copy of system modules and structures per thread and this is where multiple interpreters come in handy (e.g., the "sys" module: without one copy per thread, imports might find an already loaded module in the sys.modules table if it was imported by a different thread). See the new C API documentation at the "doc" link at www.python.org for details.
Note that you still can call Py_Initialize more than once
(despite the comments in pythonrun.c in 1.5), so the higher-level embedding
API developed in chapter 15 still works. Py_Initialize checks a static flag
to immediately return if it's already been called and Py_Finalize hasn't.
Speaking of docs: there is a new reference manual which
documents major C API tools and behavior. It's not complete yet,
but is a useful start. See the "doc" link at www.python.org,
or click here.
Back to the errata page
Back to my homepage