|
Unix Programming - Language Evaluations - Python
Python
Python is a scripting language designed for close integration with
C. It can both
import data from and export data to dynamically loaded C libraries,
and can be called as an embedded scripting language from C. Its syntax
is rather like a cross between that of C and the Modula family, but
has the unusual feature that block structure is actually controlled by
indentation (there is no analog of explicit begin/end or C curly
brackets). Python was first publicly released in 1991.
The Python language is a very clean, elegant design with
excellent modularity features. It offers designers the option to write
in an object-oriented style but does not force that choice (it can be
coded in a more classically procedural C-like way). It has a type
system comparable in expressive power to
Perl's,
including dynamic container objects and association lists, but less
idiosyncratic (actually, it is a matter of record that
Perl's object
system was built in imitation of Python's). It even pleases
Lisp hackers
with anonymous lambdas (function-valued objects that can be passed
around and used by iterators). Python ships with the Tk toolkit, which
can be used to easily build GUI interfaces.
The standard Python distribution includes client classes for
most of the important Internet protocols (SMTP, FTP, POP3, IMAP, HTTP)
and generator classes for HTML. It is therefore very well suited to
building protocol robots and network administrative plumbing. It is
also excellent for Web CGI work, and competes successfully with
Perl at the
high-complexity end of that application area.
Of all the interpreted languages we describe, Python and
Java are the
two most clearly suited for scaling up to large complex projects
with many cooperating developers. In many ways Python is simpler than
Java, and its friendliness to rapid prototyping may give it an edge
over Java for standalone use in applications that are neither hugely
complex nor speed critical. An implementation of Python in Java,
designed to facilitate mixed use of these two languages, is available
and in production use; it is called Jython.
Python cannot compete with C or C++ on raw execution speed (though using a
mixed-language strategy on today's fast processors probably makes that
relatively unimportant). In fact it's generally thought to be the
least efficient and slowest of the major scripting languages, a price
it pays for runtime type polymorphism. Beware of rejecting Python on
these grounds, however; most applications do not actually need better
performance than Python offers, and even those that appear to are
generally limited by external latencies such as network or disk waits
that entirely swamp the effects of Python's interpretive
overhead. Also, by way of compensation, Python is exceptionally easy
to combine with C, so performance-critical Python modules can be readily
translated into that language for substantial speed gains.
Python loses in expressiveness to
Perl for small
projects and glue scripts heavily dependent on regular-expression
capability. It would be overkill for tiny projects, to which
shell or
Tcl might be
better suited.
Like Perl, Python has a well-established development community
with a central website
carrying a great many useful Python implementations, tools and
extension modules.
The definitive Python reference is Programming
Python [Lutz]. Extensive
on-line documentation on Python extensions is also available at the
Python website.
Python programs tend to be quite portable between Unixes and even
across other operating systems; the standard library is powerful
enough to significantly cut the use of nonportable helper programs.
Python implementations are available for
Microsoft operating systems and for
MacOS. Cross-platform GUI development is
possible with either Tk or two other toolkits. Python/C applications
can be ‘frozen’, quasi-compiled into pure C sources that
should be portable to systems with no Python installed.
Summing up: Python's best side is that it encourages clean,
readable code and combines accessibility with scaling up well to large
projects. Its worst side is inefficiency and slowness, not just
relative to compiled languages but relative to other scripting
languages as well.
A Small Python Case Study: imgsizer
Imgsizer is a utility that rewrites WWW pages so that
image-inclusion tags get the right image size parameters
automatically plugged in (this speeds up page loading on many
browsers). You can find sources and documentation in the URL WWW tools
subdirectory of the ibiblio archive.
imgsizer was originally written in
Perl, and was a
nearly ideal example of the sort of small, pattern-driven
text-processing tool at which Perl excels. It was later translated to
Python to take advantage of Python's library support for HTTP
fetching; this eliminated a dependency on an external page-fetching
utility. Observe the use of
file(1)
and ImageMagick
identify(1)
as specialist tools for extracting the pixel sizes of images.
The dynamic string handling and sophisticated regular-expression
matching required would have made imgsizer quite painful to write in
C or C++; that version would also have been much
larger and harder to read. Java would have solved the implicit
memory-management problem, but is hardly more expressive than
C or C++ at text pattern matching.
A Medium-Sized Python Case Study:
fetchmailconf
In Chapter11 we
examined the
fetchmail/fetchmailconf
pair as an example of one way to separate implementation from
interface. Python's strengths are well illustrated by
fetchmailconf.
fetchmailconf uses the Tk
toolkit to implement a multi-panel GUI configuration editor (Python
bindings also exist for GTK+ and other toolkits, but Tk bindings ship
with every Python interpreter).
In expert mode, the GUI supports editing of about sixty
attributes divided among three panel levels. Attribute widgets include
a mix of checkboxes, radio buttons, text fields, and scrolling
listboxes. Despite this complexity, the first fully-functional version
of the configurator took me less than a week to design and code,
counting the four days it took to learn Python and Tk.
Python excels at rapid prototyping of GUI interfaces, and (as
fetchmailconf illustrates) such prototypes are often deliverable.
Perl and
Tcl have similar
strengths in this area (including the Tk toolkit, which was written
for Tcl) but are hard to control at the complexity level
(approximately 1400 lines) of fetchmailconf. Emacs
Lisp is
not suited for GUI programming. Choosing Java would have increased the complexity
overhead of this programming task without delivering significant
benefits for this nonspeed-intensive application.
A Large Python Case Study: PIL
PIL, the Python Imaging Library, supports the manipulation of
bitmap graphics. It supports many popular formats, including
PNG, JPEG, BMP, TIFF,
PPM, XBM, and GIF. Python programs can use it to convert and transform
images; supported transformations include cropping, rotation, scaling,
and shearing. Pixel editing, image convolution, and color-space
conversions are also supported. The PIL distribution includes Python
programs that make these library facilities available from the
command line. Thus PIL can be used either for batch-mode image
transformation or as a strong toolkit over which to implement
program-driven image processing of bitmaps.
The implementation of PIL illustrates the way Python can be
readily augmented with loadable object-code extensions to the Python
interpreter. The library core, implementing fundamental operations on
bitmap objects, is written in
C for speed. The upper
levels and sequencing logic are in Python, slower but much easier to
read and modify and extend.
The analogous toolkit would be difficult or impossible to write
in Emacs Lisp or shell, which don't have or don't document
a C extension interface at all. Tcl has a good C extension facility, but
PIL would be an uncomfortably large project in Tcl.
Perl has such
facilities (Perl XS), but they are ad-hoc, poorly documented, complex,
and unstable by comparison to Python's and use of them is
rare. Java's
Native Method Interface appears to provide a facility roughly
comparable to Python's; PIL would probably have made a reasonable Java
project.
The PIL code and documentation is available at the project
website.
[an error occurred while processing this directive]
|