http://www.developer.com/java/other/article.php/2170111/Introduction-to-Jython.htm
This is Chapter 1: Introduction to
Jython from the book Jython Essentials
(ISBN:0-596-00247-5) written by Samuele Pedroni and Noel Rappin, published by O'Reilly & Associates. Botanists know that if you cross-pollinate two different strains
of plants, you create a hybrid; a new plant that exhibits the strengths of
both its parents. Jython is a programming hybrid. It is an implementation of
the Python scripting language written in 100% pure Java that runs under any
compliant Java Virtual Machine (JVM). Using Jython, you can write Python
programs that interact with any Java code. The Jython interpreter supports a
number of shortcuts, which make using Java libraries as easy as using your own
Python code. Jython, then, combines a scripting language of unparalleled ease
of development with an operating environment for which many powerful tools
have been written. The combination can be immensely valuable for programmers,
enabling you to cut development time significantly while still retaining the
ability to use existing Java tools, such as applets and servlets. Just as
Python was originally conceived as glue to bind together other programs,
Jython acts as glue to help you get the most out of Java-based tools. In
particular, Jython excels at simplifying the use of complex Java programming
libraries and APIs, such as the Swing graphical interface toolkit or the JDBC
database connectivity API. This chapter is your road map to the rest of the book. We'll
start with an extended example of using Jython to interactively develop a
small graphical interface. Then we'll discuss why Jython will make it easier
for you to get things done. Finally, we'll walk through the rest of the
chapters. To run the examples in this chapter and in the rest of the book,
you need to have both Jython and a JVM installed. You can get Jython at http://www.jython.org/; see Appendix A for
full details. Unless otherwise specified, all Jython examples will run under
Jython Version 2.0 or higher, and a fully compliant JVM running Java Version
1.2 or higher. For the examples in this book, we used Sun Microsystem's Java
Development Kit, Version 1.3, but other JVMs should work as well. Before we offer arguments for why you should be using Jython,
let's first show you what Jython looks like. For your first look at Jython
we're going to do a five-finger exercise from the Jython interactive prompt,
which will show off many of Jython's features. The goal here is to give you a
sense of how the integration of Jython and Java libraries works, and how easy
it is to play with running code using Jython. In the interest of ease of
display, we're going to be a little looser with good Jython style than we'll
be in the longer examples later in the book--this is just a demonstration, but
we hope you'll find it fun and productive. You may find it useful to type
along with this exercise to really get the feel. Start by running Jython. You should see an interactive
prompt. From this prompt you can type any Jython code and see the
result. We're going to type in some Swing GUI code, so the first thing we need
to do is import Swing: Whether you are a Java or Python programmer already, that line
probably looks a little odd to you. We have told Jython to import the Java
package javax.swing and refer to it using the
identifier TIP: Throughout this book, we'll use the word
"Python" for things that are common to both Jython and the original
implementation of Python. Using the name "Jython" is usually a signal that
the concept is applicable only to Jython. Information relevant only to the
C-language implementation is referred to using the word "CPython." For
example, "Python uses indentation to determine block boundaries, Jython lets
you subclass Java classes, and CPython compiles to .pyc files." Next, we can create a window object: Nothing has happened visibly, but we can confirm that the object
has been created by typing the identifier name at the prompt. (The output probably won't be bold on your machine, we're just
doing that here for emphasis.) What we've done here is use the Python syntax
for instance creation to trigger a call to a Java class constructor. Also
notice what we did not have to do--namely, declare Now, we didn't set the size of the window. The first line of
code will do the actual set, and the second will get the value and print it to
confirm. If you are a Java programmer, that code probably looks a little
too simple to be true, because Let's get that window on the screen. Nothing happens on the command prompt, but a blank window with a
"Welcome to Jython" title, and size 200 by 200 should show up on your monitor.
If you accidentally close it, just type The window seems rather dull, so let's do something for it. We cut off the output for clarity. At the end of this sequence,
the window should have a text field in it (and probably resize itself as
well). This time, we put the preferred size setting in the call to the
constructor. As you may know, Type something in the text box. Then go back to the Jython
prompt to type: Of course, you'll get whatever you typed into the box, not what
we typed. This shows off the fact that Jython is interacting with the Java
objects in both directions--again, excellent for debugging. Now, let's put some buttons in. First, a list of names is created by enclosing the names inside
brackets. In Python, a list is similar to Java's The actual buttons are created from the list of names using a
different Python method for creating a list called a list
comprehension. The line of code can be read almost as it looks in English:
"Perform the statement Now that we have a list of buttons, we can add them to the
window with the use of a simple In the interpreter, Inside the loop, the code sets the preferred size of each button
and adds it to the window's content pane, again using the introspection
shortcuts. Once all the buttons are added, we can pack the window again. But now, the window is a mess--the buttons are placed on top of
each other, and on top of the text field. We've forgotten to give the window a
layout manager (which is the mechanism Swing uses to automatically place items
within a window). No problem, we can just add it after we import the
appropriate package. At this point, the window should look right, but it doesn't do
anything. We I want it to place some text in the text field depending on what
button you push. First, we need to create the text we want used. This line sets up a Python dictionary. A
dictionary in Python is more or less equivalent to a Java Once the text is in place, we can define a function that will
perform the actual text replacement. This pair of lines defines a function to be called when a button
is pressed. The We hope that we aren't losing credibility by suggesting that the
Python example is a little bit easier to read. Finally, we associate the function with the buttons. This Of course, Jython does not have to be run interactively. The
code that we used in the interactive shell session is shown as a standalone
file in Example
1-1. The code is equivalent to the preceding session, but we did clean it
up some, removing duplicate calls to Example 1-1: The sample standalone window Running this script from Jython (for example, by executing Having seen the interactive example, hopefully you are
interested in learning more about Jython. But you may be wondering exactly
what you might use it for. It can help to think of the JVM as a platform in
its own right. Java has been the overwhelming choice of programming language
for the JVM platform--a number of different languages other than Jython run
under a JVM in one way or another, but for most people, so far, the JVM and
Java programming have been effectively synonymous. Uses of Jython can be split
into two areas: things you might want to do within a JVM for which Java is not
a great choice, and things you might want to do where Java does seem like a
strong choice. In the first category are the kinds of programs at which
scripting languages have traditionally excelled. Programs that are small
utility tools, or one-time-only scripts, or rapid development prototypes, have
all been in the purview of scripting languages such as Python. The Java
language, for all its usability benefits over, say, C++, was not designed for
that kind of rapid development or scripting work. Jython makes that kind of
programming easier on a JVM, giving you scripting language flexibility where
it did not exist previously. This also suggests a place for Jython as an
adjunct to existing Java programs--performing cleanup and maintenance
functions, for example. Web programming is another area in the first category. Java has
made tremendous strides as a server-side web application tool over the last
few years, primarily because of the creation of really good
industrial-strength server environments. Writing the actual web application in
Java, however, is still a chore, especially when maximum response to changed
requirements is needed. Outside the Java world, many (if not most) web
applications are still written in dynamic scripting-style languages such as
ColdFusion, Perl, or Python. It's no accident that template languages or other
scripting languages written specifically for Java web applications have
proliferated. Jython as a web language gives you a scripting language that is
more powerful and established than other Java web tools such as WebMacro or
Tea, yet still gives you full access to the Java servlet libraries. Another area that Java doesn't really cover is the use of a
scripting language by your Java program. The Jython interpreter can be
embedded inside any Java program, allowing you full access to Jython for
scripting inside the program. One use of this feature common in Python is to
have your preference or properties file be a "live" Jython script, saving you
the trouble of having to convert a properties or XML file to actual
functionality. We do not, however, want to give you the impression that Jython
is good only for tasks that Java is weak at. In fact, we also think that you
will find Jython useful even for the kinds of applet or GUI applications
traditionally thought of as Java's strengths. We believe that if you decide to
prototype your program in Jython, there is a very good chance that you will
find that development of the Jython version is so smooth, you will keep the
prototype rather than port it to Java. We think that Jython is likely to improve your productivity for
a great number of project types that are currently performed in Java. In this
section, we'll start to explore the reasons why we believe this to be true.
We'll also suggest some reasons why Jython might be a good addition to your
toolkit even if you are already a CPython programmer. If you are already programming in Java, you are probably
wondering why you need another language to run under the JVM. Doesn't Java
work just fine? Sure, Java is great. But, by using Jython instead of Java,
you'll probably find that the number of lines of code in your program has
dropped by as much as 50%. Many empirical studies of programming suggest that
shorter programs have fewer bugs. In addition, programmer productivity tends
to be about the same for any number of lines of code even if, as in Jython,
each line of code tends to do more than it might in another language. In other
words, an expert Jython programmer will likely produce programs faster, and
with fewer bugs, than an expert Java programmer. We don't mean to attack Java as a programming language. Java,
like every programming language, is a tool, and it has its uses. However, it's
hard to use Java for any length of time and not realize that it is an
exceptionally verbose and often inflexible language. After you've written
lines of code such as the following, which includes a typecast that is there
only to keep the compiler happy: it becomes easier to see the benefits of just writing: The difference between the Java and Python code emphasizes one
of the main sources of the productivity advantage of Jython--dynamic typing.
In Python, you do not need to declare variables for use, nor do you need to
tell the interpreter what the expected data type of a variable is. It is
important to note that despite being dynamically typed, Python also has strong
typing. This means that a line of code such as If you have never programmed in a dynamic language, the idea of
not declaring variables or types may make you a little nervous. After all,
isn't the point of static typing to allow the compiler to catch errors before
the program runs? It's certainly true that static typing can do that. Most
programmers who switch to a dynamic language are surprised by how rarely those
errors actually occur in practice, and how quickly they are usually found and
fixed when they do occur. In Python most type errors are caught immediately the first time
you run the program--long before any users see it. Often type mistakes will
result in errors the first time a module is loaded or the first time a
function is called. Some basic unit testing makes it nearly impossible for a
type check error to get by. When compared with the amount of effort spent in
Java convincing the compiler that your program is legal, it seems that static
typing may not be worth the effort. It's worth your time to try it and see if
your experience is similar to ours. In addition to dynamic typing, the Python scripting language
used in Jython offers several other features that will improve your
programming productivity: All this additional functionality comes without having to
sacrifice integration with existing Java code. Jython code can be compiled to
Java .class or .jar files, and
these files can be distributed like any other compiled Java files--the fact
that the code was written in Jython can be made completely transparent to the
end user. If you are already a Python programmer, you know about the
programming features of Python and are probably wondering what you gain from
the Java side of the equation. There seem to be at least three important
gains. Everybody asks it, at some point. Whenever you try to sell
somebody on using a high-level scripting-style language, the question will
inevitably come up: "Isn't it slow?" As long-time programmers of scripting
languages and other languages that have been branded as slow (including Java),
we have a variety of reasons why raw benchmark speed is less important than it
might seem as a factor in choosing a programming tool. In fact, we'll also
argue that for most of you, most of the time, the speed difference is not
going to hurt at all. What is the exact magnitude of the speed difference? It's
notoriously difficult to get good information about performance across
languages. Sometimes, the person compiling the numbers has an axe to grind and
has chosen a task that favors one language. More often, the person compiling
the examples has just done a better job optimizing one version over the other.
So, any cross-language speed comparison needs to be taken with a grain of
salt. That said, one of the authors' experience in running identical
code under both Python 2.1 and Jython 2.1a3 (using Sun's JDK 1.3) suggests
that CPython takes 75% of the time that Jython does. Jython is about 1-10
times slower than equivalent Java code, although admittedly useful hard
numbers on this are hard to come by because the exact speed difference
strongly depends on the nature of your application. Programs that spend a lot
of time doing operations on primitive data types will show the largest speed
difference between Java and Jython. Jython performance is heavily dependent on the specifics of the
JVM, of course. Specifically, the Sun JDK 1.4 is expected to make significant
improvements in the performance of Java reflection, and as a result Jython
should make substantial speed gains under JVM 1.4. Still, up to 10 times slower seems like a big speed difference.
And for some programs and some projects it might be. But for most programs and
projects, the benchmark speed hit will not be as noticeable in practice as you
might think. There are four reasons why the speed loss is not as harmful in
practice as it is in benchmarks. For a large number of programs, the bottleneck is either user
input speed or network latency, and even a large performance hit in these
cases is not noticeable to users. Java programs tend to be in this category
frequently--if raw speed was the issue, you probably wouldn't be using Java in
the first place. Even for programs in which optimal performance is particularly
important, profiling will often indicate that a small number of classes or
methods are the bottleneck. In Jython, these areas can be targeted and
rewritten in Java so that you get the maximum performance benefit for the
minimum effort. There's what we might call the Peters principle, after CPython
core developer, Tim Peters. He has suggested that his Python programs often
run faster than his C programs in practice, because development is so much
easier in Python that you often wind up with a much better algorithm than you
would in C. In particular, common performance enhancements such as caching
function results are quite easy to code in Python. Finally, as in so many aspects of software design, there's a
trade off. If each run of your program takes five seconds longer, but you get
it to your users three months sooner than you otherwise would have, what's
that worth to you? How much value is created in the development time saved?
For many projects, three months of programmer time is worth far more than the
user time lost if the program is slower. For some projects, of course, the
speed is still critical. As always, the rule is "Make it work, then make it fast." Jython
is a fabulous environment for making it work, and if at some point you find
that you still need to make it faster, there are mechanisms to try, both
within Jython and by converting some code to Java. Samuele Pedroni is one of the main Jython developers. He holds a CS flavored diploma in mathematics from the ETH Zurich (Swiss institute of technology in Zurich). He is now a teacher and research assistant at the Institute of Theoretical CS. He plans to come to the US for a PhD in the field of dynamic languages and dynamic compilation. He came to Jython with the interest in improving it with respect to Java importing and reloading. He has developed several important patches related to java integration, classloaders, and the reworking of java/python importing rules and design. Noel Rappin has a Ph.D. in computer science from the Georgia Institute of Technology, where his research included methods for teaching Object-Oriented Programming and Design. He has extensive production experience in both Java and Python. Noel also contributed an introductory chapter to the book Squeak: Open Personal Computing and Multimedia (PH).
To access the full Table of Contents for the book
Introduction to Jython
March 25, 2003
Chapter 1
Introduction to
JythonJython Requirements
Welcome to Jython
Starting Jython
Jython 2.1a3 on java1.3.0 (JIT: null)
Type "copyright", "credits" or "license" for more information.
>>>
>>> import javax.swing as swing
>>>
swing. Unlike a Java import, we don't
need to tell Jython which classes to import, and unlike an ordinary Python
import, this is importing Java code that was not specifically written to
interact with Jython.
>>> win = swing.JFrame("Welcome to Jython")
>>>
>>> win
javax.swing.JFrame[frame0,0,0,0x0,invalid,hidden,layout=java.awt.
BorderLayout,resizable,title=Welcome to Jython,defaultCloseOperation=HIDE_ON_
CLOSE,rootPane=javax.swing.JRootPane[,0,0,0x0,invalid,layout=javax.swing.
JRootPane$RootLayout,alignmentX=null,alignmentY=null,border=,flags=1538,maximu
mSize=,minimumSize=,preferredSize=],rootPaneCheckingEnabled=true]win as a variable or specify a type for it in any way.
The second line uses the Python interpreter to trigger the Java toString( ) method on the win
object.>>> win.size = (200, 200)
>>> win.size
java.awt.Dimension[width=200,height=200]
size is a private
field of the window. In fact, Jython is using introspection to infer that
win.size on the left side of the assignment refers
to the size property, and automatically triggers a
Java call to win.setSize( ). On the right side of
the assignment, Jython is performing a similar inference. Taking the sequence
(200, 200), and knowing
that size is of type Dimension, Jython converts the sequence to a Java Dimension object (by calling the appropriate Dimension constructor) before making the assignment.
Similarly, the win.size standing alone in the
second line triggers a call to the Java method win.getSize( ). So, Jython allows you to write code that
retains Python's simplicity and type flexibility, but still allows the objects
to behave like Java objects.>>> win.show( )
>>>
win.show( )
again. Being able to interact with concrete objects can be of immense help in
debugging.Adding Items to the Window
>>> field = swing.JTextField(preferredSize=(200,20))
>>> win.contentPane.add(field)
javax.swing.JTextField[,0,0,200x20,. . .
>>> win.pack( )
JTextFields in Java
don't take preferred size as an argument to the constructor. Again, Jython
infers the correct property call when the object is constructed.>>> field.text
'Neat!'
>>> names = ["Groucho", "Chico", "Harpo"]
>>>
ArrayList class, but with more functionality and tighter
integration to the core language. This line shows one example of that
integration--the ability to type new lists directly without calling functions
or explicit constructors. In this example, names is
set to a list containing three strings. The assignment returns no value--in
Python, an assignment is a statement, not an expression. Python's list type is
an example of the high-level basic types that make programming in Python so
easy to manage.>>> buttons = [swing.JButton(each) for each in names]
>>>
swing.JButton( ) once for
each element in the list called names." That code
creates a new JButton with each string in the list
names as an argument. When evaluating a list
comprehension, Python holds onto the values for each statement and returns
them as a list. In this case, the variable buttons
now contains a list of three JButton instances.for loop.>>> for eachButton in buttons:
... eachButton.preferredSize = (100, 20)
... win.contentPane.add(eachButton)
...
javax.swing.JButton[,0,0,0x0,invalid,layout. . .
... is used to
indicate that the next line of code is part of a block--you don't actually
type the dots. However, you must indent the last two lines by the same amount
(at least one character) for Jython to read the block properly. The top line
of this block contains a for statement. In Python,
for statements work only for iterating over
sequences. They are roughly the equivalent of a Java Iterator, however the loop in the Python case is executed
automatically once for each element of the sequence without having to either
explicitly ask the iterator for the next object or cast the object to any
specific type. From the interpreter, a blank line indicates the end of a block
(outside the interpreter, you'd just start the next line back at column
one).>>> win.pack( )
>>> import java.awt as awt
>>> win.contentPane.layout = awt.FlowLayout( )
>>> win.pack( )
Adding Behavior
>>> quotes = {"Groucho": "Say the secret word", "Chico": "Viaduct?", "Harpo": "HONK!"}
HashMap: a collection of key/value pairs designed to be
accessed in constant time no matter which element is accessed or how large the
dictionary is. Again, the Python type is well integrated with the core
language, allowing the creation in one line of what would take a series of
put(key, value) calls in Java.>>> def buttonPressed(event):
... field.text = quotes[event.source.text]
...
>>>
event parameter in the first line
will be the actual Java Event object created from
the mouseclick. The line of code inside the function uses Jython shortcuts,
looks up the quotes dictionary with the text of the
source button, and sets the field with that value. The Java equivalent would
be something like:field.setText(quotes.get((javax.swing.JTextField) event.getSource( )).getText( )))
>>> for eachButton in buttons:
... eachButton.actionPerformed = buttonPressed
...
>>>
for loop puts the buttonPressed function in the actionPerformed slot for each button. This is another
Jython shortcut--as used in Java, buttons don't have an actionPerformed attribute. Instead, actionPerformed is the method defined inside an ActionListener interface. When you assign to actionPerformed Jython performs the appropriate call to
the button's addActionListener( ) method, such that
the function buttonPressed is triggered when the
action is performed. Also notice that Jython allows us to use a function as
the righthand side of an assignment statement, we're using the function as a
value. At this point, the window should work, and look more or less like Figure
1-1.
pack( ),
putting import and definitions where they would
more typically come in a Python module, adding code to exit Jython when the
window closes, and refactoring button creation into a separate function. Example
1-1 is typical of a Jython script as it would actually be written.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( )
jython filename at an ordinary
command prompt) will give you the same window and behavior as in Figure
1-1. What's Jython Good For?
The Benefits of Jython
For Java Programmers
MyClass instance = (MyClass)list.get(2);
instance = list[2]
"1" +
1 is an error in Python (unlike many other scripting languages, which
would quietly allow this).
instance.method( ) is determined at
runtime based on the class to which that instance
belongs. Unlike Java, Python does not test for the existence of method( ) in any particular class at compile time. This
is a corollary of dynamic typing, and has many of the same strengths and
weaknesses. However, the flexibility it gives you over Java is significant,
removing the need for Java-style interfaces and more generally promoting
code reuse by making it easier for new code to interact with existing code.
someFunc and calling it.
import java.lang.reflect.*;
Class aClass = anInstance.getClass( );
Method someFunc = aClass.getMethod("method", new Class[] {Integer, String});
someFunc.invoke(anInstance, new Object[] {new Integer(3), "Fred"});
someFunc = anInstance.method
someFunc(3, "Fred")
For Python Programmers
The Speed Question
About the Author
Source of this material

This is Chapter 1: Introduction to Jython from the book Jython Essentials (ISBN:0-596-00247-5) written by Samuele Pedroni and Noel Rappin, published by O'Reilly & Associates.