Reprinted with permission of Linux Journal.
What's been happening to Python since J. Bauer's article in Linux Journal #35? Like most free software, Python is being continually developed and enhanced. At the time of the original article, Python was at version number 1.2, and betas of 1.3 were floating around. Since then, version 1.3 has been officially released, only to be replaced by 1.4 in late October.
Versions 1.3 and 1.4 have both added new features to the language. The really significant new item in 1.3 was the addition of keyword arguments to functions, similar to Modula-3's. For example, if we have the function definition:
def curse(subject="seven large chickens",
verb="redecorate",
object="rumpus room"):
print "May", subject, verb, "your", object
then the following calls are all legal:
curse()
curse('a spaniel', 'pour yogurt on', 'hamburger')
curse(object='garage')
curse('the silent majority', object='Honda')
Arguments that aren't preceded by a keyword are passed in the usual fashion; non-keyword and keyword arguments can be used in the same function call, as long as the non-keyword parameters precede the keyword parameters. By that rule the following call is a syntax error:
curse(object='psychoanalyst', 'an ancient philosopher')
And the following call would cause an error at runtime, because an argument is being defined twice:
curse('the silent majority', subject='Honda')
As a pleasant side effect, adding keyword arguments required optimising function calls, reducing the overhead of a single function call by roughly 20%.
Most of the changes in the 1.4 release made Python more useful
for numeric tasks. Many of the changes were proposed by the members
of the Matrix special interest group (or Matrix-SIG), which has
defined a syntax and built a data type for manipulating matrices.
(The Python SIGs are small groups of people tightly focused on one
application of Python, such as numeric programming or database
interfaces; see http://www.python.org/sigs/
for more information about the existing SIGs.)
One such enhancement is support for complex numbers. The
imaginary component of a complex number is denoted by a suffix of
'J' or 'j'; thus, the square root of -1 is symbolized as
1j. The usual mathematical operations such as addition
and multiplication can be performed on complex numbers, of
course.
>> 1+2j*2 (1+4j) >> (1+2j)*2 (2+4j) >> (1+2j)/(2+1j) (0.8+0.6j)
The presence of complex numbers also requires mathematical
functions that can perform operations on them. Instead of updating
the existing math module, a new module called cmath was added; old
software might malfunction if an operation returns a complex value
where an error was expected. So math.sqrt(-1) will
always raise a ValueError exception, while
cmath.sqrt(-1) will return a complex result of
1j.
For the sake of users comfortable with Fortran's notation, the
'**' operator has been added for computing powers; it's simply a
shorthand for Python's existing pow() function. For example,
10**2 is equivalent to pow(10,2), and
returns 100.
One minor new function has been requested by several people in
comp.lang.python. Python has
long had a tuple() function which converts a sequence type (like a
string or a list) into a tuple; the usual idiom for converting
sequence types to lists was map(None, L). (
map(F,S) returns a list containing the result of
function F, performed on each of the elements of the sequence S. If
F is None, as in this case, then no operation is performed on the
elements, beyond placing them in a list.)
Many people found this asymmetry--tuple() existed, but not list()-- annoying. In 1.4 the list() function was added, which is symmetric to tuple().
>> tuple([1,2,3]) (1, 2, 3) >> list( (1,2,3,4) ) [1, 2, 3, 4]
An experimental feature was included in 1.4: private data belonging to an instance of a class is a little more private. An example will help to explain the effect of the change. Consider the following class:
class A:
def __init__(self):
self.__value=0
def get(self): return self.__value
def set(self, newval): self.__value=newval
Python doesn't support private data in classes, except by convention. The usual convention is that private variables have names that start with at least one underscore. However, users of a class can disregard this and access the private value anyway. For example:
>> instance=A() >> dir(instance) # List all the attributes of the instance ['__value'] >> instance.get() 0 >> instance.__value=5 >> instance.get() 5
A more significant problem; let's say you know nothing about A's implementation, and try to create a subclass of A which adds a new method that uses a private __value attribute of its own. The two uses of the name will collide. Things are slightly different in 1.4:
>> instance=A() >> dir(instance) ['_A__value']
Where did this new value come from? In 1.4, any attribute that
begins with two underscores is changed to have '_' and the class
name prefixed to it. Let's say you have a class called
File, and one method refers to a private variable
called __mode; the name will be changed to
_File__mode.
>> instance.get() 0 >> instance.__value=5 >> instance.get() 0 >> dir(instance) ['_A__value', '__value']
Now, this still doesn't provide ironclad data hiding; callers can just refer explicitly to _A__value. However, subclasses of A can no longer accidentally stomp on private variables belonging to A.
This feature is still controversial, and caused much debate in comp.lang.python when it was introduced. Thus, its status is only experimental, and it might be removed in a future version of the language, so it would be unwise to rely on it.
Both the 1.3 and 1.4 releases included some new modules as part of the Python library, and bug fixes and revisions to existing modules in the library. Most of these changes are only of interest to people who've written code for earlier versions of those modules; see the file Misc/NEWS in the Python source distribution for all the details. If you're just coming to the language, these changes aren't really of interest to you.
The news isn't just limited to the software. The first two books
on Python were published in October: Programming
Python, by Mark Lutz, and Internet Programming with
Python, by Aaron Watters, Guido van Rossum, and James C.
Ahlstrom. At least one more book is scheduled for release next
year. Two Python workshops have taken place, one at the Lawrence
Livermore National Labs in California last May, and another in
Washington DC in November. Speakers discussed all sorts of topics:
distributed objects; interfacing C++ and Python, or Fortran and
Python; and Web programming. See http://www.python.org/workshops/
for more information about the papers that were presented.
In November 1996, the 5th Python Workshop was held, in association with the FedUnix '96 trade show. The two most common topics were numeric programming and Web-related programming. For numeric work, there's a lot of interest in using Python as a glue language to control mathematical function libraries written in Fortran or C++. Code can be developed quickly in Python, and once the program logic is correct it can be ported to a compiled language for speed's sake. There's also a benefit from using a general programming language like Python, instead of a specialized mathematical language; it's easier to make the numeric code accessible with a GUI written in Tk, or with a CGI interface.
Another popular topic was Web-related programming. The Python
Object Publisher was an especially interesting system, which
enables accessing Python objects via HTTP. To take an example from
the Object Publisher presentation, a URL like
http://www.here.com/Car/Pinto/purchase?name=Bob causes
a Python Car object named Pinto to be
located, and its purchase() method will be called with
Bob as a parameter. Other presentations discussed
generating HTML, writing tools for system administration, and
collaborative document processing. Brief notes on the papers are at
http://www.python.org/workshops/1996-11/,
with links to HTML or PostScript versions. As you read this, plans
for the next workshop are probably in progress, though there's no
news at the time of writing; see the Python Web site for the
current status. In the past, the meetings have alternated between
the eastern and western US, so workshop #6 will probably be on the
West Coast.