Devs Using Python to Boost Integration
In this two-part interview, Martelli offers Win32, Java and .NET devs some useful perspectives on Python, and how Python scripting can extend the integration capabilities of their Win32, ASP.Net, Java and C/C++ applications.
Read the interview:
An IDN Interview
with Alex Martelli
author, "Python in a Nutshell
IDN: From your books, Python seems to be a very flexible and feature-rich scripting language. What's your best advice for a "starter" Python project aimed at extending some core enterprise applications/assets?
Martelli: Exactly because Python is a general-purpose scripting language, a typical starter project to integrate Python with an existing enterprise application might be to make the application itself "scriptable." By that, I mean to integrate the Python interpreter with the application, so that some or all of the application's functionality may be accessed from Python scripts.
IDN: Can you give more details about making applications scriptable?
Martelli: When you're extending an existing application, to make it scriptable by embedding a Python interpreter in it, you need to consider two aspects about each target application:
- If an application is internally structured as a collection of reusable components, all you need to do is to make those components Python-accessible. In other words, Python code must be enabled to "call back" into your application, in order to get information and/or effect changes to the application's state. Once your existing components can be accessed by Python, you can use Python itself to provide the "main flow of control" for all sorts of presentation layers. This strategy is known as "extending Python" because your application's reusable components are seen from Python as " extension modules. "
- If your application isn't component-oriented (and is, instead, structured as a somewhat "monolithic" executable program), you must still cover point 1 (Python code must still be enabled to call back into your application, or else it wouldn't be able to interact with it!), but you also need to do some extra work. Specifically, if your application's main flow-of-control logic must remain at the wheel at all times, then you must ensure that, within said flow, your application can load, initialize and start the Python interpreter and pass appropriate Python code to the interpreter as and when appropriate.
IDN: Does it matter what language my underlying application is written in?
Martelli: Yes, it does matter whether your existing application is coded with Java, or rather with other languages such as C, C++ and the like. Python works well in either case, but not in exactly the same way. If you start with Java, you need the Python version known as "jython," available at . If you start with C, C++ and the like, you need the Python version known as "Classic Python," available at . The two versions are highly compatible -- they're just two implementations of the same language. Classic Python is somewhat more advanced and faster, but jython is even easier to integrate with your existing applications. Both versions are freely downloadable and impose neither costs nor licensing restrictions on your applications. The "Hello World" examples of embedding I gave above use jython (for integration with Java) and Classic Python (for integration with C), respectively.
IDN: What about "jythonc"? That offers developers an alternative approach, doesn't it?
Martelli: Yes, with jythonc, having written Python code that extends Java classes and/or implements Java interfaces, you can compile that Python code to Java bytecode (i.e., build .class and/or .jar files just as you might build them from .java source files), then use the resulting bytecode files exactly as you would use them if you had started from Java source files to produce the equivalent bytecode files. jythonc is just an auxiliary program that comes with the standard jython distribution, found at .
In this case, all the rest of your application is blissfully oblivious to the fact that the source for such and such a class was in Python rather than in Java: You enjoy Python's high productivity; the ability to code some given functionality in a few tens of lines of code rather than a few hundreds, while keeping the rest of your development methods and structures quite intact. This is often particularly appropriate when you use Python to code a prototype for some new functionality: Once everything is working, you may then choose to selectively recode parts or all of the subsystem in Java, for performance reasons or if you're operating under a contract that requires you to deliver Java sources (the jythonc compiler can make Java sources from the Python sources you give it, but, as is almost invariably the case for machine-generated code, such sources are not intended to be human-readable and maintainable!).
While in many cases, you'll want the flexibility and general handiness of having a Python interpreter object explicitly available, the option of producing Java bytecode in advance is a major enhancement to the ease of integrating Python use in a Java development shop.
IDN: What about applications not written in Java? What's your advice there?
Martelli: If your application is not in Java, but rather in C, C++ and the like, you do need some work to allow Python code to "call back" into your application. You can do this by supplying suitable "Python extension modules" that reach your application's functionality.
In the Nutshell, I cover the "minimal common denominator" approach to this: Python's C API, which only uses C-level functionality and is therefore available no matter what language[s] you have coded your application in, as long as they're C-interoperable -- this of course includes C and C++, but also rarer choices such as Fortran, Delphi, Eiffel and the like.
However, if your application is coded specifically in C++, I would suggest another, more advanced approach: the Boost Python Library (available at ). Boost is a free collection of high-quality C++ libraries, centered mostly on templates -- many of them are likely to be included in the next edition of the C++ standard, since many of their developers are also very active in the C++ standardization committee. Boost Python, in particular, uses C++ templates' "metaprogramming" abilities to obtain almost as transparent and smooth interoperability beween Python and C++, as jython obtains quite differently through Java's "introspection" abilities. Unfortunately, there's currently no book that covers Boost -- but Boost does come with free tutorial and reference docs that will help you get started if you're an advanced C++ programmer, fully conversant with the awesome power and complication of C++'s templates (if you need to brush up in depth on that extremely difficult subject, I recommend Vandevoorde and Josuttis' C++ Templates (Addison-Wesley, 2002).
Another approach to help Python "call back" into your application (point 1 above) is to expose some of your application's functionality through a general-purpose componentization facility, such as COM (on Microsoft platforms) or Corba. If your application exposes COM-based components, for example, Python scripts can access those components and get to your application's functionality by calling their methods, getting and setting their properties, and so on -- just as you could do from Visual Basic and other such lower-level languages.
While this strategy has some limitations (descending from the characteristics of the component object models you may choose to employ), it may be the smoothest way for you to integrate Python if you're already supporting COM (or Corba, etc.) for other reasons.
IDN: Is Python's use of familiar developer concepts -- such as exceptions, strings and regular expressions -- something that traditional Java, ASP/.NET or legacy developers would be able to pick up quickly?
Martelli: Many of the semantics of Java and Python are really very similar -- a case of independently convergent development, no doubt, since Python was developed starting in 1990 and Java, quite independently, a bit later.
However, the similarity does mean that any Java programmer should have no trouble at all with many of Python's concepts, such as the fact that strings are immutable objects -- exactly because they're just as immutable and just as [much] "objects" in Java as in Python.
Microsoft's .NET has imitated enough of Java's concepts that the "familiarity effect" should also apply there. In fact, I'd focus on "reference semantics" as the key new concept that a legacy developer coming, for example, from C must understand in order to become productive in Java, .NET or Python.
IDN: Can you give a quick example of these "reference semantics"?
In a traditional language such as C, when I write: "a = b," I mean "make a copy of the memory contents stored in the place I call 'b', and put those copied bits into the place in memory that I call 'a'"
In Java, Python or .NET, the same "a = b" notation means something rather different: "From now on use the name 'a' to refer to the same object to which name 'b' currently refers." There's no copying involved, and a and b aren't names for chunks of memory, but rather "object references."
Java and .NET complicate this because in some cases, the "a = b" notation does mean "copy" as in traditional languages (for example, when integers or floating-point numbers are involved), and in other cases, it has the new "object reference" meaning. Python is simpler because it's regular and uniform: "a = b"always means an object-reference assignment, never means a copy (if and when you want a copy, you explicitly ask for a copy).
Thanks to this regularity and simplicity, Python is quite a bit easier to learn than Java or .NET (e.g., C# or VB.NET) languages for the legacy developer: There are no special cases, ad hoc exceptions or subtle distinctions in such fundamental operations as "a = b" assignments (and, identically, in argument passing and in returning values from functions).
Next Issue: In Part II of our interview with Martelli, IDN looks at how Python differs from Win32, Java and .NET development.