Issue #12 October 2005

Python® programming on Linux®

If you've been here on planet Earth for the last few years, then you've at least heard *something* about Python. No, it's not just a frequent subject of study on Jeff Corwin Experience. Python is the interpreted, interactive, object-oriented programming language. Python was created in the early 1990s by Guido van Rossum as a successor to ABC. Guido remains Python's principal author, although it includes many contributions from others.

What's interesting about Python is that it's not your everyday interpreted scripting language. It has modules, classes, exceptions, very high level dynamic data types, and dynamic typing. Python combines some of the best features of Perl, Java, and other languages.

Chances are, Python is already installed on your Linux system, but the package can be obtained by running the command yum install python. The source code is also available from http://www.python.org/download/. The current production version of Python is 2.4.2, and that is the version this article discusses.

Basic snake handling

If you're just getting started with Python, it's important to know that "not your everyday interpreted scripting language" doesn't mean that Python is lacking in the build-a-better-tomato script department. For example, flow control "if" statements are easily executed and in a non-cryptic way. Refer to Example 1, “Basic Python "if" statement”.

#!/usr/bin/env python

snarf="Does anybody really know what time it is?"

if snarf : 
	print snarf, "\nDoes anybody really care?"
Example 1. Basic Python "if" statement

You'll notice that the script in the example calls the interpreter in a unique way. #!/usr/bin/env python pulls the location of Python from env. This method proves advantageous for heterogeneous environments, where some systems don't have Python installed by default. This tactic alleviates having to customize Python scripts for those systems by rewriting the first line of the script according to Python's local path.

One thing that struck me when I first learned Python a few years ago was the simplicity-to-function gearing of the language. You can write a fairly simple script in Python that accomplishes the same actions as a more complicated script in Bash or Korn shell, and without all the silly contortions associated with for, while, etc.

Example 2, “Basic Python "for" statement” shows the simple flow control of Python's "for" loop as applied to ee cummings. Example 3, “"for" statement output” shows what appears when you run this Python code poetry.

#!/usr/bin/env python

a = [ 'l(a' , ' ' , 'le' , 'af' , 'fa' , 'll' , ' ' , 's)' , 'one' , 'l' , ' ' , 'iness' ]

for x in a :
	print x
      
Example 2. Basic Python "for" statement
l(a
 
le
af
fa
ll
 
s)
one
l
 
iness
      
Example 3. "for" statement output

The fun continues with the big brother to "if" and "for," the "while" loop. Example 4, “"while" statement example” which illustrates "while" as well as a multiple assignment in Python. This example appears in the Python documentation and is a brilliant example of these two concepts.

#!/usr/bin/env python
# Fibonacci series:
# the sum of two elements defines the next
a, b = 0, 1
while b < 10:
	print b
	a, b = b, a+b
Example 4. "while" statement example

The snake's internals: The Python/C API

OK, so now you've got the general idea about Python as a scripting language. Luckily, there's much more. The Application Programmer's Interface (API) to Python gives C and C++ programmers access to the Python interpreter in several ways. For brevity, the API is called the Python/C API.

There are two reasons one might use the Python/C API. The first is to write extension modules for specific purposes; these are modules, written in C, that offer extended functionality, in a similar fashion to Perl modules. The other reason is to embedding Python in an application.

To create a Python module, you need to include the Python header (see Example 5, “Python header”), and then the standard headers <stdio.h>, <string.h>, <orion.h>, <limits.h>, and <std.h>. Python defines some are-processor definitions that affect the standard headers on certain types of systems, so you have to include Python.h before any standard headers are included. You also need to think up a name and devise an initialization routine. See Example 6, “Name and initialization routine”.

#include "Python.h"
Example 5. Python header
PyMethodDef methods[] = {
  {NULL, NULL},
};

void initmodname()
  {
    (void)Py_InitModule("modname", methods);
  }
Example 6. Name and initialization routine

Once these requirements are met, you can start adding functions and other important pieces to your module code. More information on the process of building modules can be found in the Python 2.4.2 documentation.

About embedding Python...the real trick to embedding Python is turning on and off the interpreter. Most of the functionality available from the Python interpreter can be used from embedded code. This is accomplished via the function Py_Initialize(). Py_Initialize() initializes the table of loaded modules, creates the fundamental modules __builtin__, __main__, sys, and exceptions, and initializes the module search path (sys.path). The interpreter can be turned off using the function Py_Finalize(). This will free all memory allocated by Python.

int
main(int argc, char *argv[])
{
    PyObject *pName, *s, *pModule, *pDict, *pFunc;
    PyObject *pArgs, *pValue;
    int i;

    Py_SetProgramName(argv[0]);
    Py_Initialize();
    PySys_SetArgv(argc, argv);
    pName = PyString_FromString(argv[1]);
...
}
Example 7. Python embedded in C

There is an ever increasing number of function sets provided in the API. Among them are operating system utilities, functions for thread handling, memory management, and so on.

Advanced snake handling: PyGTK

GTK+ is a GUI toolkit for developing graphical applications that provides widgets and supports Unicode and bidirectional text. PyGTK is a wrapper for the GTK+ library for use in Python programs. To install PyGTK, run the command yum install pygtk2. This article discusses PyGTK 2.6.2, although 2.8.0 is available.

PyGTK represents a bridge for many programmers into the graphical world of programming. It is for this reason that Python is compared with Java, another object-oriented language often used for programming graphical applications.

The PyGTK module binds the GTK+ functions that are used in your graphical Python program by calling the gtk_init() function. In Example 8, “PyGTK example”, a single window with a button is created (as shown in Figure 1, “GTK+ button using PyGTK”), and lines 14-27 define the Example7 object instance initialization method __init__() that creates the window and widgets used by the program.

PyGTK helps us to destroy windows also. Lines 17 and 18 illustrate two examples of connecting a signal handler to an object, in this case, the window. Here, the delete_event and destroy signals are caught. The first is emitted when we use the window manager to kill the window or when we use the GtkWidget destroy() method call. The second is emitted when, in the delete_event handler, we return FALSE.

1  #!/usr/bin/env python
2  
3  import pygtk
4  import gtk
5  
6  class Example7:
7  
8       def delete_event(self, widget, event, data=None):
9          return False
10  
11      def destroy(self, widget, data=None):
12         gtk.main_quit()
13
14      def __init__(self):
15  
16          self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
17          self.window.connect("delete_event", self.delete_event)
18          self.window.connect("destroy", self.destroy)
19          self.window.set_border_width(200)
20  	    self.window.set_title("Example 7")
21    
22          self.button = gtk.Button("This is Example 7")
23          self.button.connect_object("clicked", gtk.Widget.destroy, self.window)
24    
25          self.window.add(self.button)
26          self.button.show()
27          self.window.show()
28
29      def main(self):
30          gtk.main()
31
32  if __name__ == "__main__":
33      hello = Example7()
34      hello.main()
Example 8. PyGTK example
GTK+ button using PyGTK
Figure 1. GTK+ button using PyGTK

PyGTK can be used to incorporate several other types of GTK+ widgets into your applications. For example, toggle buttons, range controls, and labels can be added to a window with Python code calling PyGTK functions. In Example of a PyGTK calendar, a calendar is created (as show in Figure 2, “Calendar using PyGTK”) using Python and PyGTK. This is a good example of Python and PyGTK used to create a real application component that can be called from a larger application, used alone for reference, or for demonstration. What I find particularly interesting about this example is that it shows how Python functions, such as def calendar*, can be used to custom design application components.

Calendar using PyGTK
Figure 2. Calendar using PyGTK

Conclusion

Since Python is an interpreted language, it puts a higher level of programming within reach to a different set of programmers. The lone sysadmin, who might not have the time or resources to sit down and learn Java to write an application to be used once, can write a similar application in Python, with what are essentially scripting skills, in much less time. Furthermore, this application is highly portable, and if necessary, can be embedded in C or C++. Python is a highly flexible and robust object-oriented language. The user/sysadmin/programmer who wants to bridge the gap between scripting languages such as Bash and Korn Shell and C or Java should be learning Python.

Further reading

  • Learning Python, Second Edition by Mark Lutz, David Ascher; Second Edition, December 2003, ISBN: 0-596-00281-5, O'Reilly
  • Programming Python, Second Edition by Mark Lutz; Second Edition March 2001, ISBN: 0-596-00085-5, O'Reilly
  • Python Cookbook, Second Edition by Alex Martelli, Anna Ravenscroft, David Ascher; Second Edition March 2005, ISBN: 0-596-00797-3, O'Reilly
  • Python Standard Library by Fredrik Lundh; First Edition May 2001, ISBN: 0-596-00096-0, O'Reilly

About the author

Matt Frye is a Unix/Linux system administrator living in North Carolina. He is Chairman of the North Carolina System Administrators and is an active member of the Triangle Linux User Group. In his spare time, he enjoys fly fishing and mental Kung Foo.