Differences between revisions 4 and 5
Revision 4 as of 2007-04-09 14:16:45
Size: 5082
Editor: DavidBoddie
Comment: I hate marking everything up with trademark symbols.
Revision 5 as of 2007-04-15 20:19:13
Size: 9861
Comment: Add some more examples
Deletions are marked like this. Additions are marked like this.
Line 2: Line 2:
Line 3: Line 4:
.. |tm| unicode:: U+8482
Line 17: Line 19:
 * Providing adaptability * Providing adaptability:
Line 19: Line 21:
 * Scripting small tasks * Scripting small tasks
Line 21: Line 23:
 * Testing * Testing
Line 23: Line 25:
 * Education and initial learning * Education and initial learning
Line 29: Line 31:
For systems written in Java\ |reg|, Jython (http://www.jython.org) is an implementation of Python written in pure For systems written in Java\ |tm|, Jython (http://www.jython.org) is an implementation of Python written in pure
Line 33: Line 35:
The following small script demonstrates using Swing from Jython::

  XXX write example
The following small script demonstrates using Swing from Jython,
and is taken from the first chapter of "Jython Essentials" by
Samuele Pedroni and Noel Rappin, published by O'Reilly & Associates
(http://www.oreilly.com/catalog/jythoness/)::

    import java.lang as lang
    import javax.swing as swing
    import java.awt as awt

    names = ["Groucho", "Chico", "Harpo"]
    quotes = {"Groucho": "Say the secret word",
     "Chico": "Viaduct?", "Harpo": "HONK!"}

    def buttonPressed(event):
  field.text = quotes[event.source.text]

    def exit(event):
 lang.System.exit(0)

    def createButton(name):
 return swing.JButton(name, preferredSize=(100,20),
  actionPerformed=buttonPressed)

    win = swing.JFrame("Welcome to Jython", size=(200, 200),windowClosing=exit)
    win.contentPane.layout = awt.FlowLayout( )

    field = swing.JTextField(preferredSize=(200,20))
    win.contentPane.add(field)

    buttons = [createButton(each) for each in names]
    for eachButton in buttons:
 win.contentPane.add(eachButton)
    win.pack()
    win.show()
Line 46: Line 79:

The following small script demonstrates using XXX from IronPython:

The IronPython web site is at http://www.codeplex.com/Wiki/View.aspx?ProjectName=IronPython.

The following small script demonstrates using the Windows Forms API
from IronPython, and is taken from Michael Foord's IronPython/Windows
Forms tutorial at
<http://www.voidspace.org.uk/ironpython/winforms/index.shtml>::

    import sys
    sys.path.append(r'C:\Python24\Lib')

    import clr
    clr.AddReference("System.Drawing")
    clr.AddReference("System.Windows.Forms")

    from System.Drawing import Point
    from System.Windows.Forms import Application, Button, Form, Label

    class HelloWorldForm(Form):
 def __init__(self):
     self.Text = 'Hello World'

     self.label = Label()
     self.label.Text = "Please Click Me"
     self.label.Location = Point(50, 50)
     self.label.Height = 30
     self.label.Width = 200

     self.count = 0

     button = Button()
     button.Text = "Click Me"
     button.Location = Point(50, 100)

     button.Click += self.buttonPressed

     self.Controls.Add(self.label)
     self.Controls.Add(button)

 def buttonPressed(self, sender, args):
     print 'The label *used to say* : %s' % self.label.Text
     self.count += 1
     self.label.Text = "You have clicked me %s times." % self.count


    form = HelloWorldForm()
    Application.Run(form)
Line 68: Line 143:
The following example uses the PAM authentication library to XXX::

  XXX write example
The following example from the pyglet multimedia library uses ctypes
to wrap some XLib functions::

    import ctypes
    from ctypes import *
    from ctypes.util import find_library as _find_library

    _libpath = _find_library('X11')
    if not _libpath:
 raise ImportError('Could not locate X11 library')
    _lib = cdll.LoadLibrary(_libpath)

    XLoadQueryFont = _lib.XLoadQueryFont
    XLoadQueryFont.restype = POINTER(XFontStruct)
    XLoadQueryFont.argtypes = [POINTER(Display), c_char_p]

    XSetAfterFunction = _lib.XSetAfterFunction
    XSetAfterFunction.restype = POINTER(CFUNCTYPE(c_int, POINTER(Display)))
    XSetAfterFunction.argtypes = [POINTER(Display), CFUNCTYPE(c_int, POINTER(Display))]
Line 83: Line 174:
The following example: XXX

XXX example
The following example is taken from the Pyrex wrapper for libxel
(https://gna.org/projects/libxel), an event logging library::

    cdef extern from "xel/xel.h":
      int xelInit(char *)
      void xelShutdown(int)
      char *xelBegin(char *, int, int)
      int xelEnd()
      void xelEnable(int)
      int xelEventF(int, char *, int, char *, char *, char *)
      int xelExportXML(char *, char *, char *)
      int xelExportCSV(char *, char *)
      int xelCheckError()
      char *xelGetError()
      char *xelGetVersion()

    class XEL:

      def __init__(self, filename=''):
 self.sid = None
 if xelInit(filename) == self.ERROR:
   raise XELError(self.geterror())

      def __del__(self):
 self.end()
 xelShutdown(self.VACUUM)

      def begin(self, name, level=LEVEL_ALL, syschk=SYSCHK_ALL):
 self.sid = xelBegin(name,level,syschk)
 if not self.sid:
   raise XELError(self.geterror())

      def end(self):
 if self.sid:
   xelEnd()
Line 99: Line 222:
The following example XXX:
The following partial examples were taken from the SWIG bindings for
the Subversion version control system (http://subversion.tigris.org/)::

    %include svn_global.swg

    %{
    #include <apr.h>
    #include <apr_general.h>

    #include "svn_md5.h"
    #include "svn_diff.h"
    %}

    #ifdef SWIGPYTHON
    %typemap(in) FILE * {
 $1 = PyFile_AsFile($input);
 if ($1 == NULL) {
     PyErr_SetString(PyExc_ValueError, "Must pass in a valid file object");
     SWIG_fail;
 }
    }
    #endif

    /* -----------------------------------------------------------------------
       wrap some specific APR functionality
    */

    apr_status_t apr_initialize(void);
    void apr_terminate(void);

    apr_status_t apr_time_ansi_put(apr_time_t *result, time_t input);

    void apr_pool_destroy(apr_pool_t *p);
    void apr_pool_clear(apr_pool_t *p);
Line 116: Line 271:
 // Define the SIP wrapper to the word library.

 %Module word 0

 class Word {

 %TypeHeaderCode
 #include <word.h>
 %End

 public:
     Word(const char *w);

     char *reverse() const;
 };
    // Define the SIP wrapper to the word library.

    %Module word 0

    class Word {

    %TypeHeaderCode
    #include <word.h>
    %End

    public:
 Word(const char *w);

 char *reverse() const;
    };
Line 143: Line 298:
 static PyObject *
 PyCurses_Is_Term_Resized(PyObject *self, PyObject *args)
 {
   int lines;
int columns;
   int result;

if (!PyArg_ParseTuple(args,"ii:is_term_resized", &lines, &columns))
     return NULL;
   result = is_term_resized(lines, columns);
   if (result == TRUE) {
     Py_INCREF(Py_True);
     return Py_True;
   } else {
     Py_INCREF(Py_False);
     return Py_False;
   }
 }
    static PyObject *
    PyCurses_Is_Term_Resized(PyObject *self, PyObject *args)
    {
      int lines;
   
int columns;
      int result;

   
if (!PyArg_ParseTuple(args,"ii:is_term_resized", &lines, &columns))
 return NULL;
      result = is_term_resized(lines, columns);
    if (result == TRUE) {
 Py_INCREF(Py_True);
 return Py_True;
      } else {
 Py_INCREF(Py_False);
 return Py_False;
      }
    }
Line 166: Line 321:
XXX

Python as a Glue Language

Introduction

The Python® language interpreter can be used as a glue language to connect software components. Components can then be manipulated by Python scripts and combined in new ways.

What can you do with scripting access to an existing system?

  • Providing adaptability:
  • Scripting small tasks
  • Testing
  • Education and initial learning

Jython for Java Components

For systems written in Java蒂, Jython (http://www.jython.org) is an implementation of Python written in pure Java that provides automatic access to Java classes from both scripts and an interactive prompt.

The following small script demonstrates using Swing from Jython, and is taken from the first chapter of "Jython Essentials" by Samuele Pedroni and Noel Rappin, published by O'Reilly & Associates (http://www.oreilly.com/catalog/jythoness/):

import java.lang as lang
import javax.swing as swing
import java.awt as awt

names = ["Groucho", "Chico", "Harpo"]
quotes = {"Groucho": "Say the secret word",
        "Chico": "Viaduct?", "Harpo": "HONK!"}

def buttonPressed(event):
     field.text = quotes[event.source.text]

def exit(event):
    lang.System.exit(0)

def createButton(name):
    return swing.JButton(name, preferredSize=(100,20),
            actionPerformed=buttonPressed)

win = swing.JFrame("Welcome to Jython", size=(200, 200),windowClosing=exit)
win.contentPane.layout = awt.FlowLayout(  )

field = swing.JTextField(preferredSize=(200,20))
win.contentPane.add(field)

buttons = [createButton(each) for each in names]
for eachButton in buttons:
    win.contentPane.add(eachButton)
win.pack()
win.show()

IronPython for CLR Components

IronPython, an implementation of Python written in C#, provides automatic access to CLR/.NET assemblies. IronPython runs on both Microsoft® .NET and on Novell® Mono. The IronPython web site is at http://www.codeplex.com/Wiki/View.aspx?ProjectName=IronPython.

The following small script demonstrates using the Windows Forms API from IronPython, and is taken from Michael Foord's IronPython/Windows Forms tutorial at <http://www.voidspace.org.uk/ironpython/winforms/index.shtml>:

import sys
sys.path.append(r'C:\Python24\Lib')

import clr
clr.AddReference("System.Drawing")
clr.AddReference("System.Windows.Forms")

from System.Drawing import Point
from System.Windows.Forms import Application, Button, Form, Label

class HelloWorldForm(Form):
    def __init__(self):
        self.Text = 'Hello World'

        self.label = Label()
        self.label.Text = "Please Click Me"
        self.label.Location = Point(50, 50)
        self.label.Height = 30
        self.label.Width = 200

        self.count = 0

        button = Button()
        button.Text = "Click Me"
        button.Location = Point(50, 100)

        button.Click += self.buttonPressed

        self.Controls.Add(self.label)
        self.Controls.Add(button)

    def buttonPressed(self, sender, args):
        print 'The label *used to say* : %s' % self.label.Text
        self.count += 1
        self.label.Text = "You have clicked me %s times." % self.count


form = HelloWorldForm()
Application.Run(form)

C/C++ Systems

The most widely used Python interpreter is the C implementation available from http://www.python.org and included in Mac OS X® and many Linux distributions. A Microsoft Windows® version is available from http://www.python.org/. A variety of tools exists to interface between Python and C code.

ctypes

The ctypes package is a foreign-function interface included with Python 2.5 and later versions that can load shared libraries (.dylib files on MacOS X, .so files on Linux, DLLs on Windows) and call arbitrary library functions.

The following example from the pyglet multimedia library uses ctypes to wrap some XLib functions:

import ctypes
from ctypes import *
from ctypes.util import find_library as _find_library

_libpath = _find_library('X11')
if not _libpath:
    raise ImportError('Could not locate X11 library')
_lib = cdll.LoadLibrary(_libpath)

XLoadQueryFont = _lib.XLoadQueryFont
XLoadQueryFont.restype = POINTER(XFontStruct)
XLoadQueryFont.argtypes = [POINTER(Display), c_char_p]

XSetAfterFunction = _lib.XSetAfterFunction
XSetAfterFunction.restype = POINTER(CFUNCTYPE(c_int, POINTER(Display)))
XSetAfterFunction.argtypes = [POINTER(Display), CFUNCTYPE(c_int, POINTER(Display))]

For more information about ctypes, refer to the ctypes section in the Python documentation (2.5 version).

Pyrex

Pyrex (http://www.cosc.canterbury.ac.nz/greg.ewing/python/Pyrex/) is a compiler that translates a Python-like language into C code for an extension module.

The following example is taken from the Pyrex wrapper for libxel (https://gna.org/projects/libxel), an event logging library:

cdef extern from "xel/xel.h":
  int   xelInit(char *)
  void  xelShutdown(int)
  char *xelBegin(char *, int, int)
  int   xelEnd()
  void  xelEnable(int)
  int   xelEventF(int, char *, int, char *, char *, char *)
  int   xelExportXML(char *, char *, char *)
  int   xelExportCSV(char *, char *)
  int   xelCheckError()
  char *xelGetError()
  char *xelGetVersion()

class XEL:

  def __init__(self, filename=''):
    self.sid = None
    if xelInit(filename) == self.ERROR:
      raise XELError(self.geterror())

  def __del__(self):
    self.end()
    xelShutdown(self.VACUUM)

  def begin(self, name, level=LEVEL_ALL, syschk=SYSCHK_ALL):
    self.sid = xelBegin(name,level,syschk)
    if not self.sid:
      raise XELError(self.geterror())

  def end(self):
    if self.sid:
      xelEnd()

SWIG for C/C++ libraries across languages

SWIG, the Simple Wrapper Interface Generator (http://www.swig.org), parses C/C++ header files and custom interface descriptions, generating C code for an extension wrapping the C functions and data types. SWIG can use the same input to generate wrappers for several different language environments; supported languages other than Python include Perl, Tcl, Ruby, PHP, Java, and Common Lisp.

The following partial examples were taken from the SWIG bindings for the Subversion version control system (http://subversion.tigris.org/):

%include svn_global.swg

%{
#include <apr.h>
#include <apr_general.h>

#include "svn_md5.h"
#include "svn_diff.h"
%}

#ifdef SWIGPYTHON
%typemap(in) FILE * {
    $1 = PyFile_AsFile($input);
    if ($1 == NULL) {
        PyErr_SetString(PyExc_ValueError, "Must pass in a valid file object");
        SWIG_fail;
    }
}
#endif

/* -----------------------------------------------------------------------
   wrap some specific APR functionality
*/

apr_status_t apr_initialize(void);
void apr_terminate(void);

apr_status_t apr_time_ansi_put(apr_time_t *result, time_t input);

void apr_pool_destroy(apr_pool_t *p);
void apr_pool_clear(apr_pool_t *p);

SIP for C++ libraries

SIP (http://www.riverbankcomputing.co.uk/sip/) parses interface specifications to create Python bindings for C and C++ libraries. Originally written for wrapping the Qt® libraries from Trolltech®, SIP is now used for other projects as well.

The following SIP example wraps a C++ class called Word, making the class constructor and the reverse() method available as a Python module called word.

// Define the SIP wrapper to the word library.

%Module word 0

class Word {

%TypeHeaderCode
#include <word.h>
%End

public:
    Word(const char *w);

    char *reverse() const;
};

Python's C API

The Python interpreter has a documented C API for writing extension modules. Writing simple wrappers atop a C library is a straightforward task

The following example from Python's source code wraps the is_term_resized() function provided by the curses screen-handling library:

static PyObject *
PyCurses_Is_Term_Resized(PyObject *self, PyObject *args)
{
  int lines;
  int columns;
  int result;

  if (!PyArg_ParseTuple(args,"ii:is_term_resized", &lines, &columns))
    return NULL;
  result = is_term_resized(lines, columns);
  if (result == TRUE) {
    Py_INCREF(Py_True);
    return Py_True;
  } else {
    Py_INCREF(Py_False);
    return Py_False;
  }
}

Embedding Python

XXX

AdvocacyWritingTasks/GlueLanguage (last edited 2008-11-15 14:00:19 by localhost)

Unable to edit the page? See the FrontPage for instructions.