Jython 2
Jython 2
Programming essentials
Presented by developerWorks, your source for great tutorials
ibm.com/developerWorks
Table of Contents
If you're viewing this document online, you can click any of the topics below to link directly to that section.
2
5
13
25
29
34
40
46
54
58
67
73
76
Page 1 of 100
ibm.com/developerWorks
To benefit from the discussion, you should be familiar with at least one procedural
programming language and the basic concepts of computer programming, including
command-line processing. To fully utilize Jython's features you should also be familiar
Page 2 of 100
ibm.com/developerWorks
with the basic concepts of object-oriented programming. To fully understand the GUI
application example at the end of the tutorial you should have prior experience with
Swing GUI programming, although you will be able to glean a lot from the preceding
discussion and examples. It will also be helpful to have a working knowledge of the
Java platform, because Jython runs on a JVM; although this is not a requirement of the
tutorial.
Note that this tutorial is oriented towards Windows systems. All command examples
will employ Windows syntax. In most cases similar commands perform the same
functions on UNIX systems, although these commands will not be demonstrated.
Page 3 of 100
ibm.com/developerWorks
Page 4 of 100
ibm.com/developerWorks
Objects in Jython
Jython is an object-oriented language that completely supports object-oriented
programming. Objects defined by Jython have the following features:
Identity: Each object must be distinct and this must be testable. Jython supports the
is and is not tests for this purpose.
State: Each object must be able to store state. Jython provides attributes (a.k.a.
fields or instance variables) for this purpose.
Behavior: Each object must be able to manipulate its state. Jython provides
methods for this purpose.
Note that the id(object) built-in function returns a unique integer identity value. So,
the expression x is y is equivalent to id(x) == id(y).
Page 5 of 100
ibm.com/developerWorks
Defining a class
Defining a class is a lot like defining a module in that both variables and functions can
be defined. Unlike the Java language, Jython allows the definition of any number of
public classes per source file (or module). Thus, a module in Jython is much like a
package in the Java language.
We use the class statement to define classes in Jython. The class statement has
the following form:
statement
When you define a class, you have the option to provide zero or more assignment
statements. These create class attributes that are shared by all instances of the class.
You can also provide zero or more function definitions. These create methods. The
superclasses list is optional. We'll discuss superclasses a little later in the tutorial.
The class name should be unique in the same scope (module, function, or class). The
class name is really a variable bound to the class body (similar to any other
assignment). In fact, you can define multiple variables to reference the same class.
Page 6 of 100
ibm.com/developerWorks
create an instance of a class you call the class as if it were a function. There is no need
to use a new operator like in C++ or the Java language. For example, with the class
class MyClass:
pass
x = MyClass()
x.attr1 = 1
x.attr2 = 2
:
x.attrN = n
class MyClass:
attr1 = 10
attr2 = "hello"
# class attributes
def method1(self):
print MyClass.attr1
Page 7 of 100
ibm.com/developerWorks
method4 = method3
Note that inside a class, you should qualify all references to class attributes with the
class name (for example, MyClass.attr1) and all references to instance attributes
with the self variable (for example, self.text). Outside the class, you should
qualify all references to class attributes with the class name (for example,
MyClass.attr1) or an instance (for example, x.attr1) and all references to
instance attributes with an instance (for example, x.text, where x is an instance of
the class).
Hidden variables
To achieve data hiding, it is often desirable to create "private" variables, which can be
accessed only by the class itself. Jython provides a naming convention that makes
accessing attributes and methods outside the class difficult. If you declare names of the
form: __xxx or __xxx_yyy (that's two leading underscores), the Jython parser will
automatically mangle (that is, add the class name to) the declared name, in effect
creating hidden variables. For example:
class MyClass:
__attr = 10
def method1(self):
pass
def method2(self, p1, p2):
pass
def __privateMethod(self, text):
self.__text = text
# private attribute
Note that unlike C++ and the Java language, all references to instance variables must
be qualified with self; there is no implied use of this.
Page 8 of 100
class Class1:
def __init__ (self):
self.data = []
class Class2:
def __init__ (self, v1, v2):
self.v1 = v1
self.v2 = v2
ibm.com/developerWorks
# no arguments
# set implicit data
# 2 required arguments
# set data from parameters
class Class3:
def __init__ (self, values=None): # 1 optional argument
if values is None: values = []
self.values = values
# set data from parameter
class Class:
def __init__ (self, db):
self.connection = db.getConnection()
self.connection.open()
def __del__ (self):
self.close()
# establish a connection
# cleanup at death
def close(self):
# cleanup
if not self.connection is None and self.connection.isOpen():
self.connection.close()
# release connection
self.connection = None
Page 9 of 100
ibm.com/developerWorks
:
x = instanceMaker(MyClass)
Inheritance
The ability to inherit from classes is a fundamental to object-oriented programming.
Jython supports both single and multiple-inheritance. Single inheritance means there
can be only one superclass; multiple inheritance means there can be more than one
superclass.
Inheritance is implemented by subclassing other classes. These classes can be either
other Jython classes or Java classes. Any number of pure-Jython classes or Java
interfaces can be superclasses but only one Java class can be (directly or indirectly)
inherited from. You are not required to supply a superclass.
Any attribute or method in a superclass is also in any subclass and may be used by the
class itself or any client (assuming it is publicly visible). Any instance of a subclass can
be used wherever an instance of the superclass can be used -- this is an example of
polymorphism. These features enable reuse, rapid development, and ease of
extension.
Below are some examples of inheritance:
# no inheritance
# single inheritance
Page 10 of 100
ibm.com/developerWorks
class Class1(SuperClass):
def __init__ (self):
SuperClass.__init__(self)
self.data = []
class Class2(SuperClass):
def __init__ (self, v1, v2):
SuperClass.__init__(self, v1)
self.v2 = v2
# no arguments
# init my super-class
# set implicit data
# 2 required arguments
# init my super-class with v1
# no arguments
# init each super-class
# set implicit data
class Class1:
def method1 (self):
:
class Class2(Class1):
def method1 (self):
:
Class1.method1(self)
:
# override method1
# call my super-class method
# override method1
# call my super-class method
Page 11 of 100
ibm.com/developerWorks
:
def method3 (self):
:
Note that the secondary method definitions (in Class2 and Class3) override the
superclass definitions. There is no requirement that the subclass method call its
superclass method; however, if it doesn't, then it must completely replace the function
of the superclass method.
Calling methods
There are two syntaxes for calling methods (assuming you have an instance of
MyClass referenced by variable mci):
mci.someMethod(...)
MyClass.someMethod(mci, ...)
The first form typically is used in class client coding while the second one is used more
often in subclasses to call superclass methods.
Page 12 of 100
ibm.com/developerWorks
Special attributes
Jython classes provide support for several special attributes. The most significant are
shown below:
Name
Role
Comment(s)
__dict__
__class__
__bases__
A tuple of the
Can be used to introspect the
immediate superclasses superclasses of the object
of the object
x = SomeClass()
print isinstance(x, SomeClass)
#
print isinstance(x, SomeOtherClass) #
:
# change the class (that is, the type)
x.__class__ = SomeOtherClass
print isinstance(x, SomeClass)
#
prints: 1 (true)
prints: 0 (false)
of the instance here
prints: 0 (false)
Page 13 of 100
ibm.com/developerWorks
# prints: 1 (true)
y = SomeOtherClass()
print x.__class__ == y.__class__
# prints: 1 (true)
After this change, the x instance will support the methods of SomeOtherClass, not
SomeClass as it did previously. Take care when changing the class of an object that
the instance has the right attributes for the new class.
Page 14 of 100
ibm.com/developerWorks
if __name__ == "__main__":
from UserList import UserList
class MyClass(UserList):
def __init__ (self, x, y):
UserList.__init__(self)
self.__x = x
self.__y = y
def method1 (self):
return self.x + self.y
def method2 (self, x, y):
return self.x + self.y + x + y
print "For class:", `MyClass`
printObject(MyClass)
print
aMyClass = MyClass(1, 2)
aMyClass.extend([1,2,3,4])
print "For instance:", `aMyClass`
printObject(aMyClass)
Page 15 of 100
ibm.com/developerWorks
running the main code from the above module. Notice that the private fields and
methods (see Hidden variables on page 8 ) have mangled names.
UserList.__len__
UserList.__lt__
UserList.__mul__
UserList.__ne__
UserList.__radd__
UserList.__repr__
UserList.__rmul__
UserList.__setitem__
UserList.__setslice__
UserList.append
UserList.count
UserList.extend
UserList.index
UserList.insert
UserList.pop
UserList.remove
UserList.reverse
UserList.sort
Note that methods and class attributes reside with classes and instance attributes
reside with instances. Yet all the class's methods can be applied to each instance.
Introspection
You will often need to determine, at runtime, the characteristics of an object. We call
this introspecting the object. The Java platform offers introspection services via the
java.lang.Class class and classes in the java.lang.reflect package. While
powerful, these APIs are somewhat difficult to use. As you probably already suspected,
Jython offers a simpler approach to introspection.
In Jython, we can use the dir and vars functions to examine the bindings for any
object, such as modules, functions, classes, sequences, maps, and more. To better
understand how this works, consider the following example. The output has been
inserted (and reformatted) after the print statements prefixed with "..." for easier
reading. The dir function returns only the binding names, while the vars function
returns the names and values; thus, when the same names are returned by both
Page 16 of 100
ibm.com/developerWorks
=
=
=
=
=
1
2
3
[x, y, z]
{x:"xxxx", y:"yyyy", z:"zzzz"}
Page 17 of 100
ibm.com/developerWorks
Comment(s)
hasattr(obj, name)
getattr(obj, name {,
default})
setattr(obj, name,
Page 18 of 100
ibm.com/developerWorks
value)
delattr(obj, name)
See Appendix K: Built-in functions on page 95 to learn more about these functions.
Abstract classes
Abstract classes are classes in which some or all of the methods are missing or have
incomplete definitions. A subclass must be created to provide or complete these
method definitions. Concrete classes are not abstract (that is, all the methods are
complete). So far we have been working only with concrete classes. Abstract classes
are created to facilitate reuse. They provide a partial implementation of a design that
you can complete or extend by subclassing them.
To get a better understanding of how this works, we will create a simple abstract
command framework that supports command do, undo, and redo actions. Commands
are defined in (sub)classes and can be added easily by creating new do_... and
undo_... methods. We access these methods via introspection, as discussed in the
previous panels.
class CommandProcessor:
# an abstract class
""" Process Commands. """
def __init__ (self):
self.__history = []
self.__redo = []
def execute (self, cmdName, *args):
""" Do some command """
self.__history.append( (cmdName, args) )
processor = getattr(self, "do_%s" % cmdName, None)
if processor:
return processor(*args)
else:
raise NameError, "cannot find do_%s" % cmdName
def undo (self, count=1):
""" Undo some (or all) commands in LIFO order """
self.__redo = []
Page 19 of 100
ibm.com/developerWorks
Note:This example is based on code from Jython Essentials by Samuele Pedroni and
Noel Rappin (see Resources on page 73 for more information).
Page 20 of 100
print
print
print
print
print
"execute:"
"execute:"
"execute:"
"undo:
"
"redo:
"
;
;
;
;
;
ibm.com/developerWorks
mp.execute("Cmd1", None)
mp.execute("Cmd2", (1,2,3))
mp.execute("Cmd3", "Hello")
mp.undo(2)
mp.redo(2)
The framework with the given test case produces the following output:
execute:
Do Command 1: None
execute:
Do Command 2: (1, 2, 3)
execute:
Do Command 3: Hello
undo:
Undo Command 3: Hello
Undo Command 2: (1, 2, 3)
redo:
Do Command 2: (1, 2, 3)
Do Command 3: Hello
execute:
Traceback (innermost last):
File "cmdproc.py", line 63, in ?
File "cmdproc.py", line 15, in execute
NameError: cannot find do_BadCmd
Operator overloading
Like C++, but unlike the Java language, Jython allows many of the standard language
operators to be overloaded by classes. This means classes can define a specific
meaning for the language operators. Jython also allows classes to emulate built-in
types like numbers, sequences, and maps. To learn more about emulation see
Appendix B: Common overloaded operators and methods on page 76 .
In the example that follows, we'll use the standard Jython UserList class definition to
show an example of operator overloading in practice. UserList is a class that wraps
a list and behaves as a list does. Most of its function is delegated (passed on to) its
contained list, called data. In a more realistic example, these overloaded functions
would be implemented to access some other store, such as a disk file or a database.
class UserList:
def __init__(self, initlist=None):
self.data = []
if initlist is not None:
if
type(initlist) == type(self.data):
self.data[:] = initlist
elif isinstance(initlist, UserList):
Page 21 of 100
ibm.com/developerWorks
self.data[:] = initlist.data[:]
else:
self.data = list(initlist)
def __cast(self, other):
if isinstance(other, UserList): return other.data
else:
return other
# `self`, repr(self)
def __repr__(self): return repr(self.data)
# self < other
def __lt__(self, other): return self.data <
self.__cast(other)
self.__cast(other)
Page 22 of 100
ibm.com/developerWorks
Page 23 of 100
ibm.com/developerWorks
Nested classes
Like functions, classes can be nested. Nested classes in Jython work similarly to static
inner classes in the Java language. Here's an example:
class MyDataWrapper:
class Data: pass
Page 24 of 100
ibm.com/developerWorks
:
def myFunc(x):
print "x at entry:", x
:
print "x at exit:", x
return x
:
z = myFunc(20)
Page 25 of 100
ibm.com/developerWorks
Page 26 of 100
ibm.com/developerWorks
> C:\Articles\<string>(1)?()->None
(Pdb) next
C:\Articles>
To learn more about debugging with the Jython debugger, see Appendix C: Jython
debugger commands on page 79 .
Jython profiler
Sometimes you may notice that a Jython program runs longer than you expect. You
can use the Jython profiler to find out what sections of the program take the longest
time and optimize them. The profiler will let you profile entire programs or just individual
functions.
Here's an example run, profiling the factor.py program (see The factorial engine:
factor.py on page 67 ):
filename:lineno(function)
<string>:0(?)
factor.py:0(?)
\
factor.py:34(calculate)
factor.py:5(Factorial)
factor.py:6(__init__)
factor.py:61(doFac)
\
profile:0(profiler)
From this run you can see that (besides the initial startup code) most of the program
time is being used by the calculate function. For more information on profiling
Page 27 of 100
ibm.com/developerWorks
Assertions
Like C and the Java language (as of version 1.4), Jython supports assertions.
Assertions are conditions that must be true for the program to work correctly; if they are
not true the program may behave unpredictably. Often they are used to validate input
values to functions. Jython's support for assertions comes in the form of the following
assert statement:
:
def myFunc(x):
assert x >= 0, "argument %r must be >= 0" % x
return fac(x)
:
z = myFunc(20)
# no exception raised
z = myFunc(-1)
Page 28 of 100
# AssertionError raised
ibm.com/developerWorks
After being compiled by jythonc the above class can be used in Java code anywhere
an java.util.ArrayList instance can be used. Note that when calling a
superclass method, the self value is passed as an argument.
Page 29 of 100
ibm.com/developerWorks
<type> get<name>()
-- and -void set<name>(<type> value)
For example the Java methods long getTime() { ... } and void
setTime(long t) { ... } define the long property time. Thus a Jython reference
d.time is automatically and dynamically converted into the Java expression
d.getTime().
Jython can also set properties, thus d.time = 1000000L is allowed. The Jython
reference d.time = value is automatically and dynamically converted into the Java
expression d.setTime(value). Once this change is applied, the print statement
from Calling Java classes from Jython on page 30 results in the following:
Page 30 of 100
ibm.com/developerWorks
1:
2:
3:
4:
5:
6:
7:
This code sequence creates and shows a GUI frame window. The script's first
command-line argument becomes the title and the second the content text. Line 4
creates the frame, passing in the title, the desired size, and a close action. The size
and defaultCloseOperation parameters are properties as described above and,
as such, may be (quite conveniently) set in the JFrame's constructor when invoked
from a Jython program. The title is set as a parameter of the JFrame's equivalent of
the __init__ method. Line 6 accesses the JFrame's contentPane property and
calls its add method to add a JLabel to show the second argument. Line 7 makes the
frame visible by setting its visible property to 1 (true).
A sample of this GUI is shown below:
Page 31 of 100
ibm.com/developerWorks
Jython does not support overloaded methods, which are methods with the same name
but with differing number and/or types of arguments. Instead, Jython supports
defaulted arguments and variable number of arguments, which can create a problem if
you inherit from a Java class that uses overloading and you want to override the
overloaded methods. In Jython, you must define the base method and accept a varying
number of arguments. Consider the (rather impractical) example of an InputStream
that always returns a blank:
Page 32 of 100
ibm.com/developerWorks
Array support is provided by the jarray module. The two functions in the jarray
module, zeros and array, are used to create arrays. The array function maps a
Jython sequence to a Java array. Some examples are as follows:
See Appendix A: Character codes for array types on page 76 for a listing of character
codes for array types.
Page 33 of 100
ibm.com/developerWorks
start_new_thread(function, args)
-- and -exit()
The start_new_thread function runs the function argument in a new Java thread,
passing the args tuple value to the function. The exit function can be used in the
thread to end it (generally as the target of an if statement).
Java synchronization
When developing multithreaded programs using Java or Jython threads, it is
sometimes necessary to create synchronized functions (or methods). Synchronized
functions are functions that can only be called from one thread at a time; meaning that
other threads are prevented from entering the function until the first thread exits. Jython
provides the synchronized module and two functions to create synchronized
functions. The functions are of the following form:
make_synchronized(function)
-- and -apply_synchronized(syncobj, function, pargs {, kwargs})
Page 34 of 100
ibm.com/developerWorks
Page 35 of 100
ibm.com/developerWorks
Page 36 of 100
ibm.com/developerWorks
class Producer:
def __init__ (self, name, buffer):
self.__name = name
self.__buffer = buffer
def __add (self, item):
self.__buffer.add(item)
def __produce (self, *args):
for item in args:
self.__add(item)
def produce (self, items):
start_new_thread(self.__produce, tuple(items))
class Consumer:
def __init__ (self, name, buffer):
self.__name = name
self.__buffer = buffer
def __remove (self):
item = self.__buffer.get()
return item
def __consume (self, count):
for i in range(count):
self.__remove()
def consume (self, count=1):
start_new_thread(self.__consume, (count,))
=
=
=
=
=
Producer("P1",
Producer("P2",
Producer("P3",
Producer("P4",
Consumer("C1",
buf)
buf)
buf)
buf)
buf)
Page 37 of 100
ibm.com/developerWorks
c2 = Consumer("C2", buf)
# create 6 items
p1.produce(["P1 Message " + str(i) for i in range(3)])
p2.produce(["P2 Message " + str(i) for i in range(3)])
# consume 20 items
for i in range(5):
c1.consume(2)
c2.consume(2)
# create 20 more items
p3.produce(["P3 Message " + str(i) for i in range(10)])
p4.produce(["P4 Message " + str(i) for i in range(10)])
# consume 4 items
c1.consume(2)
c2.consume(2)
# let other threads run
lang.Thread.currentThread().sleep(5000)
xprint("Buffer has %i item(s)left" % len(buf))
Added: P1 Message 0
Added: P1 Message 1
Added: P1 Message 2
Added: P2 Message 0
Added: P2 Message 1
Added: P2 Message 2
Removed: P1 Message
Removed: P1 Message
Removed: P1 Message
Removed: P2 Message
Removed: P2 Message
Removed: P2 Message
Added: P3 Message 0
Removed: P3 Message
Added: P3 Message 1
Removed: P3 Message
Added: P3 Message 2
Removed: P3 Message
Added: P3 Message 3
Removed: P3 Message
Added: P3 Message 4
Removed: P3 Message
Added: P3 Message 5
Page 38 of 100
0
1
2
0
1
2
0
1
2
3
4
Added: P3 Message 7
Removed: P3 Message
Added: P3 Message 8
Removed: P3 Message
Added: P3 Message 9
Removed: P3 Message
Added: P4 Message 0
Removed: P4 Message
Added: P4 Message 1
Removed: P4 Message
Added: P4 Message 2
Removed: P4 Message
Added: P4 Message 3
Removed: P4 Message
Added: P4 Message 4
Added: P4 Message 5
Added: P4 Message 6
Added: P4 Message 7
Added: P4 Message 8
Added: P4 Message 9
Removed: P4 Message
Removed: P4 Message
Removed: P4 Message
7
8
9
0
1
2
3
4
5
6
Removed: P3 Message 5
Added: P3 Message 6
Removed: P3 Message 6
ibm.com/developerWorks
Removed: P4 Message 7
Buffer has 2 item(s)left
Page 39 of 100
ibm.com/developerWorks
""" This module defines several functions to ease interfacing with Java code."""
from types import *
from java import lang
from java import util
from java import io
# only expose these
__all__ = ['loadProperties', 'getProperty',
'mapToJava', 'mapFromJava', 'parseArgs']
Page 40 of 100
ibm.com/developerWorks
source = io.FileInputStream(source)
bis = io.BufferedInputStream(source)
props = util.Properties()
props.load(bis)
bis.close()
for key in props.keySet().iterator():
result[key] = props.get(key)
return result
def getProperty (properties, name, default=None):
""" Gets a property. """
return properties.get(name, default)
import sys
file = sys.argv[1]
props = loadProperties(file)
print "Properties file: %s, contents:" % file
print props
print "Property %s = %i" % ('debug', int(getProperty(props, 'debug', '0')))
Page 41 of 100
ibm.com/developerWorks
Page 42 of 100
ibm.com/developerWorks
prints:
data: (1, 2, 3, [1, 2, 3], ['H', 'e', 'l', 'l', 'o', '!'], 'Hello!', \
{2: 'two', 1: 'one'})
toJava: [1, 2, 3, [1, 2, 3], [H, e, l, l, o, !], Hello!, {2=two, 1=one}]
fromJava: [1, 2, 3, [1, 2, 3], ['H', 'e', 'l', 'l', 'o', '!'], 'Hello!', \
{2: 'two', 1: 'one'}]
type(data)=org.python.core.PyTuple
type(toJava)=org.python.core.PyJavaInstance
type(fromJava)=org.python.core.PyList
Notice that the PyTuple became a PyJavaInstance and then a PyList. Also notice
that the toJava form formats differently. This is because it is a Java object and it's
being printed by the Java toString() method, not Jython repr() function.
PyJavaInstance is a type Jython will pass as is to a Java API. Finally, notice that the
data and fromJava values are the same except that the tuple is now an equivalent
list. For more about Jython types see Appendix L: Jython types summary on page 99 .
Page 43 of 100
ibm.com/developerWorks
# a positional argument
Page 44 of 100
ibm.com/developerWorks
Page 45 of 100
ibm.com/developerWorks
name
addr
v1 =
s1 =
sent
="Barry Feigenbaum"
= '12345 Any Street"
100; v2 = v1 * 1.5; v3 = -v2; v4 = 1 / v2
"String 1"; s2 = "String 2"
= "The rain in Spain falls mainly on the plain."
Page 46 of 100
ibm.com/developerWorks
line:
print "abc" + "xyz"
prints: abcxyz.
To select a character or characters (that is, a substring) from a string you use indexing.
For example: "abcxwy"[2] yields c, while "abcxwy"[2:4] yields cx.
Many of the string functions test conditions, thus they are often used in conjunction with
the if and while statements. Here's an example of how we could use containment
testing to see if a character were contained in a string:
In addition to testing conditions, strings also support methods to test the nature of the
string. These are islower, isupper, isalnum, isnum, isalpha, isspace, and
istitle. These methods test to see if all the characters in the strings meet these
conditions.
Additional methods
Strings support several methods that allow you to find and edit sub-strings, change
case, and a host of other actions. To find a string in another string use the find/rfind
or startswith/endswidth methods. For example:
Sometimes you need to edit the content of a string, for example to change its case or
insert or remove text from it. Jython supplies several methods to do this. To change
case, Jython has the lower, upper, swapcase, title, and capitalize methods.
To change the text of a string, use the replace method. For example, to match strings
often you want to ignore case or you may want to replace sub-strings:
if
-- or --
Page 47 of 100
ibm.com/developerWorks
Often strings have extra blanks around them that are not important, such as when the
string is entered by a user. To remove these extra blanks use the lstrip, rstrip, or
strip methods. For example, to match a command entered by a user:
Often you need to break strings into parts, such as the words in a sentence or join
multiple strings into one string. Jython supports the split, splitlines, and join
functions to do this. The split method splits a line into words, while splitlines
splits a file of lines into separate lines. The join method reverses split. You can
also join strings by concatenation as discussed above. For example, to extract the
words from a sentence and then rebuild the sentence use:
Page 48 of 100
ibm.com/developerWorks
Below are some format (%) operator examples. See Appendix J: Formatting strings
and values on page 94 for more examples.
Expression
Result
Hello Barry
"This is %i%%" % 10
This is 10%
print:
Page 49 of 100
ibm.com/developerWorks
Pretty printing
You can use the pprint module functions, in particular the pformat function, to print
complex data structures in a formatted form. For example, this code:
Unformatted:
[[1, 2, 3], [4, 5, 6], {'2': 'two', '1': 'one'}, \
'jsdlkjdlkadlkad', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]]
Formatted:
[[1, 2, 3],
[4, 5, 6],
{'2': 'two', '1': 'one'},
'jsdlkjdlkadlkad',
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]]
import sys
def stripLines (lines):
""" Removed extra whitespace (that is, newlines). """
newlines = []
Page 50 of 100
ibm.com/developerWorks
"""
# current page
# current line
Page 51 of 100
ibm.com/developerWorks
self.alignment == "left":
adjust = firstline * self.pindent
#line = line
Page 52 of 100
ibm.com/developerWorks
Page 53 of 100
ibm.com/developerWorks
Regular
expression
Matches
Does not
match
-- none --
abc
abc
ab
aabc
abcc
. - any character
a.c
abc
ac
axc
abbc
ac
* - optional repeating
subpattern
a.*c
abc
abcd
axc
ac
ac
Page 54 of 100
ibm.com/developerWorks
axxxxc
? - optional subpattern
a.?c
abc
ac
aabc
+ - required repeating
subpattern
a.+c
abc
ac
abbc
abcd
axxc
...|... - choice of subpattern
(...) - grouping
abc|def
a(xx)|(yy)c
abcef
abef
abdef
abcdef
axxc
axc
ayyc
ayc
axxyyc
(...)* - repeating grouping
a(xx)*c
ac
axxbxxc
axxc
axxxxc
(...)+ - required repeating
grouping
a(xx)+c
\c - match a special
character
\.\?\*\+
a\s*z
axxc
ac
axxxxc
axxbxxc
.?*+
?.*+
abcd
az
za
az
za
abyz
Comment(s)
Page 55 of 100
ibm.com/developerWorks
match(pattern, string {,
options})
search(pattern, string {,
options})
findall(pattern, string)
split(pattern, string {,
max})
subn(pattern, repl, string {, Substitutes the match with repl for max
max})
or all occurrences; returns the tuple
(result, count)
Note that the matching functions return None if no match is found. Otherwise the
match functions will return a Match object from which details of the match can be
found. See the Python Library Reference for more information on Match objects.
import re
# do a fancy string match
if re.search(r"^\s*barry\s+feigenbaum\s*$", name, re.I):
print "It's Barry alright"
# replace the first name with an initial
name2 = re.sub(r"(B|b)arry", "B.", name)
If you are going to use the same pattern repeatedly, such as in a loop, you can speed
up execution by using the compile function to compile the regular expression into a
Pattern object and then using that object's methods, as shown here:
import re
patstr = r"\s*abc\s*"
pat = re.compile(patstr)
# print all lines matching patstr
for s in stringList:
if pat.match(s, re.I): print "%r matches %r" % (s, patstr)
Page 56 of 100
ibm.com/developerWorks
When run on the words.txt file from File I/O in Jython on page 58 , the program produces
the following result:
Page 57 of 100
ibm.com/developerWorks
The mode string has the following syntax: (r|w|a){+}{b}; the default mode is r.
Here is a listing of all the available access mode strings:
r: read
w: write
a: append to the end of the file
+: update
b: binary (vs. text)
The name of the file is accessed through the name attribute. The mode of the file is
accessed through the mode attribute.
Comment(s)
close()
flush()
read({size})
readline({size})
readlines()
Page 58 of 100
ibm.com/developerWorks
ending '\n')
seek(offset {, mode})
tell()
truncate({size})
write(string)
writelines(lines)
import sys
f = open(sys.argv[1], "rb")
bin = f.read()
f.close()
f = open(sys.argv[2], "wb")
f.write(bin)
f.close()
import sys
f = open(sys.argv[1], "r")
# read the file by lines
lines = f.readlines()
f.close()
lines.sort()
# sort and print the lines
print "File %s sorted" % f.name
print lines
Page 59 of 100
ibm.com/developerWorks
import sys
def clean (word):
""" Remove any punctuation and map to a common case. """
word = word.lower()
# remove any special characters
while word and word[-1] in ".,;!": word = word[:-1]
while word and word[0] in ".,;!": word = word[1:]
return word
words = {}
if len(sys.argv) != 2:
print "Usage: jython wcount.py <file>"
else:
file = open(sys.argv[1]) # access file for read
lines = file.readlines() # get the file
file.close()
# process each line
for line in lines:
# process each word in the line
for word in line.split():
word = clean(word)
words[word] = words.get(word, 0) + 1
Output of words.txt
Given the following input file (words.txt)
Now is the time for all good men to come to the aid of their country.
The rain in Spain falls mainly on the plain.
How many times must I say it; Again! again! and again!
Singing in the rain! I'm singing in the rain! \
Just singing, just singing, in the rain!
3
1
1
1
1
again
aid
all
and
come
Page 60 of 100
1
1
1
1
1
many
men
must
now
of
1
1
1
1
1
1
1
4
1
1
2
1
country
falls
for
good
how
i
i'm
in
is
it
just
mainly
1
1
4
1
4
1
7
1
1
1
2
ibm.com/developerWorks
on
plain
rain
say
singing
spain
the
their
time
times
to
import java.io.*;
import java.util.*;
import java.text.*;
public class WordCounter
{
protected static final String specials = ".,;!";
/** Remove any punctuation and map to a common case. */
protected static String clean(String word) {
word = word.toLowerCase();
// remove any special characters
while (word.length() > 0 &&
specials.indexOf(word.charAt(word.length() - 1)) >= 0) {
word = word.substring(0, word.length() - 1);
}
while (word.length() > 0 &&
specials.indexOf(word.charAt(0)) >= 0) {
word = word.substring(1);
}
return word;
}
protected static Map words = new HashMap();
public static void main(String[] args) throws IOException {
if (args.length != 1) {
System.out.println("Usage: java WordCounter <file>");
}
else {
// access file for read
Page 61 of 100
ibm.com/developerWorks
Printing to files
The print statement can print to a file by use of the ">>" operator. By default it prints
to the console (actually the value of sys.stdout). For example, the following
commands are equivalent:
Page 62 of 100
ibm.com/developerWorks
import sys
print >>sys.stdout, "Hello world!"
Jython allows alternate target files. For example, to print to the standard error stream
use:
f = open("myfile", "w")
for i in range(10):
print >>f, "Line", i
f.close()
f = open("myfile", "a")
print >>f, "Added line"
f.close()
Comment(s)
load(file)
loads(string)
dump(object, file {,
bin})
dumps(object{, bin})
Page 63 of 100
ibm.com/developerWorks
A pickling example
Here's an example of pickle at work. The following code sequence
import pickle
class Data:
def __init__ (self, x, y):
self.__x = x
self.__y = y
def __str__ (self):
return "Data(%s,%s)" % (self.__x, self.__y)
def __eq__ (self, other):
return self.__x == other.__x and self.__y == other.__y
data = Data(10, "hello")
file = open("data.pic", 'w')
pickle.dump(data, file)
file.close()
file = open("data.pic", 'r')
newdata = pickle.load(file)
file.close()
print
print
print
print
"data:", data
"newdata:", newdata
"data is newdata:", data is newdata
"data == newdata:", data == newdata
prints this:
data: Data(10,hello)
newdata: Data(10,hello)
data is newdata: 0 (false)
data == newdata: 1 (true)
The file created is in (semi-)readable plain text. For example, the above code created
the file data.pic:
(i__main__
Data
p0
Page 64 of 100
ibm.com/developerWorks
(dp1
S'_Data__y'
p2
S'hello'
p3
sS'_Data__x'
p4
I10
sb.
Note that Jython cannot pickle objects that are Java objects, reference Java objects, or
subclass Java classes. To do this you need to use the
java.io.ObjectOutputStream and java.io.ObjectInputStream classes.
Object shelves
As shown in the previous panel, Jython can store objects into a file. Using a file per
object can cause problems (that is, it can waste space and you will need to name each
file). Jython supports a file that can hold multiple objects, called a shelf. A shelf acts
much like a persistent dictionary. To create shelves, use the open function of module
shelve. For example, the following code:
# create shelf
shelf = shelve.open("test.shelf")
clearshelf(shelf)
shelf["x"] = [1,2,3,4]
shelf["y"] = {'a':1, 'b':2, 'c':3}
printshelf(shelf)
shelf.close()
print
# update shelf
shelf = shelve.open("test.shelf")
printshelf(shelf)
print
shelf["z"] = sys.argv[1]
printshelf(shelf)
shelf.close()
print
# verify shelf persistent
Page 65 of 100
ibm.com/developerWorks
shelf = shelve.open("test.shelf")
printshelf(shelf)
shelf.close()
x = [1, 2, 3, 4]
y = {'b': 2, 'a': 1, 'c': 3}
x = [1, 2, 3, 4]
y = {'b': 2, 'a': 1, 'c': 3}
x = [1, 2, 3, 4]
z = This is a test string
y = {'b': 2, 'a': 1, 'c': 3}
x = [1, 2, 3, 4]
z = This is a test string
y = {'b': 2, 'a': 1, 'c': 3}
Note that the open function produces two files based on the file name passed to open:
<filename>.dir is a directory into the persistent data
<filename>.dat is the saved persistent object data
Page 66 of 100
ibm.com/developerWorks
Page 67 of 100
ibm.com/developerWorks
Page 68 of 100
ibm.com/developerWorks
if next != last:
# signal progress
self.fireListeners(next)
last = next
self.fireListeners(100) # 100% done
if self.__cancelled: result = -1
return result
# test case
if __name__ == "__main__":
print sys.argv[0], "running..."
fac = Factorial()
def doFac (value):
try:
print "For", value, "result =", fac.calculate(value)
except ValueError, e:
print "Exception -", e
doFac(-1)
doFac(0)
doFac(1)
doFac(10)
doFac(100)
doFac(1000)
Page 69 of 100
ibm.com/developerWorks
self.running = 0
-- Java thread body
def run (self):
self.complete =
if self.__param
self.result
else:
self.result
self.complete =
0; self.running = 1
is not None:
= self.__runner(self.__param)
= self.__runner()
1; self.running = 0
Page 70 of 100
ibm.com/developerWorks
Page 71 of 100
ibm.com/developerWorks
Page 72 of 100
ibm.com/developerWorks
Resources
Download the jython2-source.zip for this tutorial.
Visit the Jython home page to download Jython.
Take the first part of this tutorial "Introduction to Jython, Part 1: Java programming
made easier" (developerWorks, April 2004).
Jython modules and packages enable reuse of the extensive standard Java libraries.
Learn more about the Java libraries (and download the current version of the JDK)
on the Sun Microsystems Java technology homepage.
You'll find an entire collection of Python docs and tutorials (including the Python
Library Reference) and more information about regular expressions on the Python
Page 73 of 100
ibm.com/developerWorks
home page.
You can also learn more about regular expressions from the tutorial "Using regular
expressions" (developerWorks, September 2000).
Greg Travis's "Getting started with NIO" (developerWorks, July 2003) is a good,
hands-on introduction to the Java platform's new I/O.
In "Charming Jython" (developerWorks, May 2003) regular developerWorks
contributor Uche Ogbuji offers a short introduction to Jython.
Try your hand at using Jython to build a read-eval-print-loop, with Eric Allen's "Repls
provide interactive evaluation" (developerWorks, March 2002).
Charming Python is regular developerWorks column devoted to programming with
Python.
Jeffrey Friedl's Mastering Regular Expressions, Second Edition (O'Reilly, July 2002)
is a comprehensive introduction to regular expressions.
For a solid introduction to Jython, see Samuele Pedroni and Noel Rappin's Jython
Essentials (O'Reilly, March 2002).
Jython for Java Programmers focuses on application development, deployment, and
optimization with Jython (Robert W. Bill, New Riders, December 2001).
Python Programming with the Java Class Libraries is a good introduction to building
Web and enterprise applications with Jython (Richard Hightower, Addison Wesley,
2003).
You'll find articles about every aspect of Java programming in the developerWorks
Java technology zone.
Visit the Developer Bookstore for a comprehensive listing of technical books,
including hundreds of Java-related titles .
Also see the Java technology zone tutorials page for a complete listing of free
Java-focused tutorials from developerWorks.
Feedback
Page 74 of 100
ibm.com/developerWorks
Page 75 of 100
ibm.com/developerWorks
'z'
Boolean
'c'
char
'b'
byte
'h'
short
'i'
int
'l'
long
'f'
float
'd'
double
Function to override
Comment(s)
x+y
__add__(self, other)
Implements + operator
x += y
+x
__iadd__(self, other)
__pos__ self)
x-y
__sub__(self, other)
x -= y
__rsub__(self, other)
-x
__isub__(self, other)
Page 76 of 100
Implements - operator
ibm.com/developerWorks
__neg__(self)
x*y
__mul__(self, other)
x *= y
__rmul__(self, other)
Implements * operator
__imul__(self, other)
x/y
__div__(self, other)
x /= y
__rdiv__(self, other)
Implements / operator
__idiv__(self, other)
x%y
__mod__(self, other)
x %= y
__rmod__(self, other)
Implements % operator
__imod__(self, other)
x&y
__and__(self, other)
x &= y
__rand__(self, other)
__iand__(self, other)
x|y
__or__(self, other)
x |= y
__ror__(self, other)
Implements | operator
__ior__(self, other)
x^y
__xor__(self, other)
x ^= y
__rxor__(self, other)
Implements ^ operator
__ixor__(self, other)
~x
__invert__(self)
Implements ~ operator
x << y
__lshift__(self, other)
x <<= y
__rlshift__(self, other)
__ilshift__(self, other)
x >> y
__rshift__(self, other)
x >>= y
__ rrshift__(self, other)
__ irshift__(self, other)
x ** y
__pow__(self, other)
x **= y
__rpow__(self, other)
Implements ** operator
__ipow__(self, other)
divmod(x,y)
__divmod__(self, other)
Implements divmod()
__rdivmod__(self, other)
Introduction to Jython, Part 2: Programming essentials
Page 77 of 100
ibm.com/developerWorks
x<y
__lt__(self, other)
x <= y
__le__(self, other)
x>y
__gt__(self, other)
x >= y
__ge__(self, other)
x == y
__eq__(self, other)
x != y
__ne__(self, other)
cmp(x,y)
__cmp__(self, other)
__nonzero__(self)
hash(x)
__hash__(self)
abs(x)
__abs__(self)
Implements abs()
int(x)
__int__(self)
Implements int()
long(x)
__long__(self)
Implements long()
float(x)
__float__(self)
Implements float()
complex(x)
__complex__(self)
Implements complex()
oct(x)
__oct__(self)
Implements oct()
hex(x)
__hex__(self)
Implements hex()
coerce(x,y)
__coerce__(self, other)
Implements coerce()
x <> y
Page 78 of 100
ibm.com/developerWorks
y = x.name
x.name = y
del x.name
y = c[i]
__getitem_ (self, i)
c[i] = y
__setitem__ (self, i)
del c[i]
__delitem__ (self, i)
x(arg, ...)
len(c)
__len__ (self)
Implements len()
x in c
Implements in operator
class()
del x
__del__ (self)
repr(x)
__repr__(self)
__str__(self)
x not in c
-- or -`x`
str(x)
Note: For the binary operators, the __xxx__ form is used when the left (or both)
argument implements the function; the __rxxx__ form is used only if the right argument
implements the function and the left argument does not; the __ixxx__ form is used to
implement the augmented assignment (x ?= y) operation. See the Python Reference
Manual for more details and overload-able functions.
Arguments
Function
h, help
-- none --
w, where
-- none --
Page 79 of 100
ibm.com/developerWorks
d, down
-- none --
u, up
-- none --
b, break
line# | function,
condition_expr
tbreak
line# | function,
condition_expr
cl, clear
bpid...
enable
bpid...
Enables breakpoints
disable
bpid...
Disabled breakpoints
ignore
bpid, count
condition
bpid, condition_expr
s, step
-- none --
n, next
-- none --
r, return
-- none --
c, cont,
continue
-- none --
Resume execution
j, jump
line#
l, list
line#1, line#1
a, args
-- none --
p, pp
expr
expr
alias
name, expr
unalias
name
Delete an alias
q, quit
-- none --
Page 80 of 100
statement
ibm.com/developerWorks
char
Boolean
Integer
float, double
Float
Class or JavaClass
Foobar[]
java.lang.Object
org.python.core.PyObject
All unchanged
Foobar
char
Boolean
Integer
float, double
Float
java.lang.String
String
java.lang.Class
Page 81 of 100
ibm.com/developerWorks
Foobar[]
Note: the above two tables are from the www.jython.org site.
Comment(s)
argv
maxint
minint
platform
path
stdin
stdout
stderr
modules
version
version_info
The sys module has some important functions:
Function
Comment(s)
exit(int)
exc_info()
Page 82 of 100
ibm.com/developerWorks
Comment(s)
name
Type of host
curdir
pardir
sep
pathsep
linesep
environ
Comment(s)
getcwd()
mkdir(path)
Create/delete a directory
makedirs(path)
rmdir(path)
remove(path)
Delete a file
-- or -unlink(path)
listdir(path)
rename(path, new)
system(command)
Page 83 of 100
ibm.com/developerWorks
Comment(s)
exists(path)
abspath(path)
normpath(path)
normcase(path)
basename(path)
dirname(path)
commonprefix(list)
gethome()
getsize(path)
isabs(path)
isfile(path)
isdir(path)
samepath(path1, path2)
join(list)
split(path)
splitdrive(path)
splitext(path)
Comment(s)
Page 84 of 100
ibm.com/developerWorks
below
.
??
+?
*?
{m,n}
{m,n}?
[...]
[^...]
...|...
(...)
(?...)
(?=...)
(?!...)
\c
Special characters:
\c literal escapes: .?*+&^$|()[]
\c function escapes: see below
Comment(s)
\A
Page 85 of 100
ibm.com/developerWorks
\Z
\B
\b
\D
\d
\S
\s
\W
\w
\#
Matches group #
Several options exist to modify how regular expression are processed. Options are bit
flags and may be combined by OR-ing (|) them together. Some of the more useful
options are:
Option
Comment(s)
IGNORECASE
-- or -I
MULTILINE
-- or --
M
DOTALL
-- or -S
import org.python.core.*;
Page 86 of 100
ibm.com/developerWorks
Page 87 of 100
ibm.com/developerWorks
funcTable, 0,
null, null, 0, 1);
c$1_addListener = Py.newCode(2,
new String[]
{"self", "listener", "ll"},
"C:\\Articles\\factor.py",
"addListener", false,
false, funcTable, 1,
null, null, 0, 1);
c$2_addListeners = Py.newCode(2,
new String[]
{"self", "listeners", "l"},
"C:\\Articles\\factor.py",
"addListeners", false,
false, funcTable, 2,
null, null, 0, 1);
c$3_removeListener = Py.newCode(2,
new String[]
{"self", "listener", "ll"},
"C:\\Articles\\factor.py",
"removeListener", false,
false, funcTable, 3,
null, null, 0, 1);
c$4_removeListeners = Py.newCode(2,
new String[]
{"self", "listeners", "l"},
"C:\\Articles\\factor.py",
"removeListeners", false,
false, funcTable, 4,
null, null, 0, 1);
c$5_fireListeners = Py.newCode(2,
new String[]
{"self", "value", "func"},
"C:\\Articles\\factor.py",
"fireListeners", false,
false, funcTable, 5,
null, null, 0, 1);
c$6_cancel = Py.newCode(1,
new String[]
{"self"},
"C:\\Articles\\factor.py",
"cancel", false,
false, funcTable, 6,
null, null, 0, 1);
c$7_calculate = Py.newCode(2,
new String[]
{"self", "value", "next",
"x", "last", "result"},
"C:\\Articles\\factor.py",
"calculate", false,
false, funcTable, 7,
null, null, 0, 1);
c$8_Factorial = Py.newCode(0,
new String[]
{},
"C:\\Articles\\factor.py",
"Factorial", false,
false, funcTable, 8,
Page 88 of 100
ibm.com/developerWorks
Page 89 of 100
ibm.com/developerWorks
Page 90 of 100
ibm.com/developerWorks
t$1$PyObject =
frame.getlocal(0).__getattr__("_Factorial__listeners");
while ((t$0$PyObject =
t$1$PyObject.__finditem__(t$0$int++)) != null) {
frame.setlocal(2, t$0$PyObject);
frame.getlocal(2).__call__(frame.getlocal(1));
}
return Py.None;
}
private static PyObject cancel$7(PyFrame frame) {
frame.getlocal(0).__setattr__("_Factorial__cancelled", i$1);
return Py.None;
}
private static PyObject calculate$8(PyFrame frame) {
// Temporary Variables
int t$0$int;
PyObject t$0$PyObject, t$1$PyObject;
// Code
if (((t$0$PyObject = frame.getglobal("type").
__call__(frame.getlocal(1)).
_ne(frame.getglobal("types").
__getattr__("IntType"))).__nonzero__()
? t$0$PyObject
: frame.getlocal(1)._lt(i$0)).__nonzero__()) {
throw Py.makeException(
frame.getglobal("ValueError"),
s$2._add(frame.getglobal("str").
__call__(frame.getlocal(1))));
}
frame.getlocal(0).__setattr__("_Factorial__cancelled", i$0);
frame.setlocal(5, l$3);
frame.getlocal(0).invoke("fireListeners", i$0);
if (frame.getlocal(1)._le(i$1).__nonzero__()) {
frame.setlocal(5, l$3);
}
else {
frame.setlocal(4, i$0);
t$0$int = 0;
t$1$PyObject = frame.getglobal("range").
__call__(i$1,frame.getlocal(1)._add(i$1));
while ((t$0$PyObject = t$1$PyObject.
__finditem__(t$0$int++)) != null) {
frame.setlocal(3, t$0$PyObject);
if (frame.getlocal(0).
__getattr__("_Factorial__cancelled").__nonzero__()) {
break;
}
frame.setlocal(5,
frame.getlocal(5)._mul(frame.getlocal(3)));
frame.setlocal(2,
frame.getlocal(3)._mul(i$4)._div(frame.getlocal(1)));
if
(frame.getlocal(2)._ne(frame.getlocal(4)).__nonzero__()) {
frame.getlocal(0).invoke("fireListeners",
frame.getlocal(2));
Page 91 of 100
ibm.com/developerWorks
frame.setlocal(4, frame.getlocal(2));
}
}
}
frame.getlocal(0).invoke("fireListeners", i$4);
if (frame.getlocal(0).
__getattr__("_Factorial__cancelled").__nonzero__()) {
frame.setlocal(5, i$1.__neg__());
}
return frame.getlocal(5);
}
private static PyObject Factorial$9(PyFrame frame) {
frame.setlocal("__init__",
new PyFunction(frame.f_globals,
new PyObject[] {}, c$0___init__));
frame.setlocal("addListener",
new PyFunction(frame.f_globals,
new PyObject[] {}, c$1_addListener));
frame.setlocal("addListeners",
new PyFunction(frame.f_globals,
new PyObject[] {}, c$2_addListeners));
frame.setlocal("removeListener",
new PyFunction(frame.f_globals,
new PyObject[] {}, c$3_removeListener));
frame.setlocal("removeListeners",
new PyFunction(frame.f_globals,
new PyObject[] {}, c$4_removeListeners));
frame.setlocal("fireListeners",
new PyFunction(frame.f_globals,
new PyObject[] {}, c$5_fireListeners));
frame.setlocal("cancel",
new PyFunction(frame.f_globals,
new PyObject[] {}, c$6_cancel));
frame.setlocal("calculate",
new PyFunction(frame.f_globals,
new PyObject[] {}, c$7_calculate));
return frame.getf_locals();
}
private static PyObject doFac$10(PyFrame frame) {
// Temporary Variables
PyException t$0$PyException;
// Code
try {
Py.printComma(s$7);
Py.printComma(frame.getlocal(0));
Py.printComma(s$8);
Py.println(frame.getglobal("fac").
invoke("calculate", frame.getlocal(0)));
}
catch (Throwable x$0) {
t$0$PyException = Py.setException(x$0, frame);
if (Py.matchException(t$0$PyException,
frame.getglobal("ValueError"))) {
frame.setlocal(1, t$0$PyException.value);
Py.printComma(s$9);
Page 92 of 100
ibm.com/developerWorks
Py.println(frame.getlocal(1));
}
else throw t$0$PyException;
}
return Py.None;
}
private static PyObject main$11(PyFrame frame) {
frame.setglobal("__file__", s$12);
frame.setlocal("sys",
org.python.core.imp.importOne("sys", frame));
frame.setlocal("types",
org.python.core.imp.importOne("types", frame));
frame.setlocal("exceptions",
org.python.core.imp.importOne("exceptions", frame));
frame.setlocal("Factorial",
Py.makeClass("Factorial",
new PyObject[] {},
c$8_Factorial, null));
if (frame.getname("__name__")._eq(s$5).__nonzero__()) {
Py.printComma(frame.getname("sys").
__getattr__("argv").__getitem__(i$0));
Py.println(s$6);
frame.setlocal("fac",
frame.getname("Factorial").__call__());
frame.setlocal("doFac",
new PyFunction(frame.f_globals,
new PyObject[] {}, c$9_doFac));
frame.getname("doFac").__call__(i$1.__neg__());
frame.getname("doFac").__call__(i$0);
frame.getname("doFac").__call__(i$1);
frame.getname("doFac").__call__(i$10);
frame.getname("doFac").__call__(i$4);
frame.getname("doFac").__call__(i$11);
}
return Py.None;
}
}
public static void moduleDictInit(PyObject dict) {
dict.__setitem__("__name__", new PyString("factor"));
Py.runCode(new _PyInner().getMain(), dict, dict);
}
public static void main(String[] args) throws java.lang.Exception {
String[] newargs = new String[args.length+1];
newargs[0] = "factor";
System.arraycopy(args, 0, newargs, 1, args.length);
Py.runMain(factor._PyInner.class, newargs,
factor.jpy$packages,
factor.jpy$mainProperties, null,
new String[] {"factor"});
}
}
Page 93 of 100
ibm.com/developerWorks
Note: The above code has been reformatted for line length.
%{(key)}{flag}...{width}{.precision}x
Page 94 of 100
Result Format
Comment(s)
ibm.com/developerWorks
%s, %r
String
%i, %d
Integer Decimal
Unsigned Value
%f, %F
Floating Decimal
Exponential
%c
Character
%%
Character
The % character
Note: more details on the structure and options of the format item can be found in the
Python Library Reference (Resources on page 73 ). Use of case in format characters
(for example, X vs x causes the symbol to show in matching case.
For example
prints
Use/Comment(s)
Example(s)
abs(x)
Absolute value
abs(-1) --> 1
apply(func, pargs
{, kargs})
-- or --
Page 95 of 100
ibm.com/developerWorks
func(*pargs {,
**kargs})
callable(x)
chr(x)
cmp(x, y)
Compares x to y: returns:
negative if x < y; 0 if x == y;
positive if x > y
coerce(x, y)
compile(text,
name, kind)
complex(r, i)
dir({namespace})
divmod(x, y)
execfile(name
{,globals {,
locals}})
execfile("myfile.py")
filter(func, list)
Creates a list of items for which filter(lambda x: x > 0, [-1, 0, 1, -5, 10])
func returns true
--> [1, 10]
float(x)
Converts x to a float
getattr(object,
name {, default})
setattr(object,
Page 96 of 100
ibm.com/developerWorks
name, value)
object's attribute
hasattr(object,
name)
globals()
locals()
hash(object)
hex(x)
id(object)
input(prompt)
int(10.2) --> 10
int("10") --> 10
int("1ff", 16) --> 511
isinstance(object,
class)
issubclass(xclass,
clsss)
len(x)
len("Hello") --> 5
list(seq)
tuple(seq)
long(x {, radix})
Page 97 of 100
ibm.com/developerWorks
long("10000000000") -->
10000000000L
map(func, list, ...)
max(x)
max(1,2,3) --> 3
max([1,2,3]) --> 3
min(x)
min(1,2,3) --> 1
min([1,2,3]) --> 1
oct(x)
ord(x)
ord('\t') --> 9
pow(x,y)
Computes x ** y
pow(2,3) --> 8
pow(x,y,z)
Computes x ** y % z
range({start,} stop
{, inc})
reduce(func, list {,
init})
repr(object)
-- or --
`object`
round(x {, digits})
str(object)
Page 98 of 100
Converts to human-friendly
string
ibm.com/developerWorks
type(object)
Returns the type (not the same x = "1"; type(x) is type('') --> 1
as class) of the object. To get
the class use
object.__class__. Module
types has symbolic names for
all Jython types
zip(seq, ...)
Comment(s)
ArrayType
PyArray
BuiltinFunctionType
PyReflectedFunction
BuiltinMethodType
PyMethod
ClassType
PyClass
ComplexType
PyComplex
DictType
PyDictionary
FileType
PyFile
FloatType
PyFloat
FunctionType
PyFunction
InstanceType
PyInstance
-- none --
PyJavaInstance
IntType
PyInteger
LambdaType
PyFunction
-- or -DictionaryType
Page 99 of 100
ibm.com/developerWorks
expression object
ListType
PyList
LongType
PyLong
MethodType
PyMethod
ModuleType
PyModule
NoneType
PyNone
StringType
PyString
TracebackType
PyTraceback
TupleType
PyTuple
TypeType
PyJavaClass
UnboundMethodType
PyMethod
UnicodeType
PyString
XRangeType
PyXRange
Note: several types map to the same Java runtime type. For more information on types
see the Python Library Reference (Resources on page 73 ).
Colophon
This tutorial was written entirely in XML, using the developerWorks Toot-O-Matic tutorial
generator. The open source Toot-O-Matic tool is an XSLT stylesheet and several XSLT
extension functions that convert an XML file into a number of HTML pages, a zip file, JPEG
heading graphics, and two PDF files. Our ability to generate multiple text and binary formats
from a single source file illustrates the power and flexibility of XML. (It also saves our
production team a great deal of time and effort.)
You can get the source code for the Toot-O-Matic at
www6.software.ibm.com/dl/devworks/dw-tootomatic-p. The tutorial Building tutorials with the
Toot-O-Matic demonstrates how to use the Toot-O-Matic to create your own tutorials.
developerWorks also hosts a forum devoted to the Toot-O-Matic; it's available at
www-105.ibm.com/developerworks/xml_df.nsf/AllViewTemplate?OpenForm&RestrictToCategory=11.
We'd love to know what you think about the tool.