Skip to main content

By clicking Submit, you agree to the developerWorks terms of use.

The first time you sign into developerWorks, a profile is created for you. Select information in your developerWorks profile is displayed to the public, but you may edit the information at any time. Your first name, last name (unless you choose to hide them), and display name will accompany the content that you post.

All information submitted is secure.

  • Close [x]

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerworks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

By clicking Submit, you agree to the developerWorks terms of use.

All information submitted is secure.

  • Close [x]

Introduction to Jython, Part 2: Programming essentials

Barry Feigenbaum, Sr. Consulting IT Architect, IBM

Dr. Barry Feigenbaum is a member of the IBM Worldwide Accessibility Center, where he is part of team that helps IBM make its own products accessible to people with disabilities. Dr. Feigenbaum has published several books and articles, holds several patents, and has spoken at industry conferences such as JavaOne. He serves as an Adjunct Assistant Professor of Computer Science at the University of Texas, Austin.

Dr. Feigenbaum has more than 10 years of experience using object-oriented languages like C++, Smalltalk, the Java programming language, and Jython. He uses the Java language and Jython frequently in his work. Dr. Feigenbaum is a Sun Certified Java Programmer, Developer, and Architect.


Acknowledgements

I would like to acknowledge Mike Squillace and Roy Feigel for their excellent technical reviews of this tutorial.

Summary:  This is the second installment in a two-part tutorial designed to introduce you to the Jython scripting language. Part 1 covered the basics of Jython, including installation and setup, access options and file compilation, syntax and data types, program structure, procedural statements, and functions. In Part 2 you will delve into some of the more advanced aspects of working with this powerful scripting language, starting with an in-depth introduction to object-oriented programming with Jython. You'll also learn about topics essential to the mechanics of application development in any language, including debugging, string processing, and file I/O.

Date:  08 Apr 2004
Level:  Introductory

Activity:  25194 views
Comments:  

Appendices

Appendix A: Character codes for array types

The table below lists the character codes for Jython array types (see Java arrays from Jython).

Character type code Corresponding Java type
'z' Boolean
'c' char
'b' byte
'h' short
'i' int
'l' long
'f' float
'd' double

Note: The above table is from www.jython.org.

Appendix B: Common overloaded operators and methods

The following are the operators that are commonly (additional operators can be) overloaded:

Operator Function to override Comment(s)
x + y
x += y
+x
__add__(self, other)
__radd__ (self, other)
__iadd__(self, other)
__pos__ self)
Implements + operator
x - y
x -= y
-x
__sub__(self, other)
__rsub__(self, other)
__isub__(self, other)
__neg__(self)
Implements - operator
x * y
x *= y
__mul__(self, other)
__rmul__(self, other)
__imul__(self, other)
Implements * operator
x / y
x /= y
__div__(self, other)
__rdiv__(self, other)
__idiv__(self, other)
Implements / operator
x % y
x %= y
__mod__(self, other)
__rmod__(self, other)
__imod__(self, other)
Implements % operator
x & y
x &= y
__and__(self, other)
__rand__(self, other)
__iand__(self, other)
Implements & operator
x | y
x |= y
__or__(self, other)
__ror__(self, other)
__ior__(self, other)
Implements | operator
x ^ y
x ^= y
__xor__(self, other)
__rxor__(self, other)
__ixor__(self, other)
Implements ^ operator
~ x __invert__(self) Implements ~ operator
x << y
x <<= y
__lshift__(self, other)
__rlshift__(self, other)
__ilshift__(self, other)
Implements << operator
x >> y
x >>= y
__rshift__(self, other)
__ rrshift__(self, other)
__ irshift__(self, other)
Implements >> operator
x ** y
x **= y
__pow__(self, other)
__rpow__(self, other)
__ipow__(self, other)
Implements ** operator
divmod(x,y) __divmod__(self, other)
__rdivmod__(self, other)
Implements divmod()
x < y __lt__(self, other) Implements < operator. This should return the opposite value returned by __ge__.
x <= y __le__(self, other) Implements <= operator. This should return the opposite value returned by __gt__.
x > y __gt__(self, other) Implements > operator. This should return the opposite value returned by __le__.
x >= y __ge__(self, other) Implements >= operator. This should return the opposite value returned by __lt__.
x == y __eq__(self, other) Implements == operator. This should return the opposite value returned by __ne__.
x != y
x <> y
__ne__(self, other) Implements != operator. This should return the opposite value returned by __eq__.
cmp(x,y) __cmp__(self, other) Implements cmp(); also used for relational tests if above specific overrides are not defined. This should return a < 0, 0 or > 0 value (say -1, 0 or 1).
x __nonzero__(self) Implements logical tests. This should return 0 or 1.
hash(x) __hash__(self) Implements hash(). Returns an integer value. Instances that are equal (that is, __eq__ returns true) should return the same __hash__ value (that is, (x == y) and (hash(x) == hash(y)) should be true. Similar to java.lang.Object.hashCode().
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()
y = x.name __getattr__ (self, name) Implements attribute lookup
x.name = y __setattr__ (self, name) Implements attribute creation/update
del x.name __delattr__ (self, name) Implements attribute removal
y = c[i] __getitem_ (self, i) Implements item lookup
c[i] = y __setitem__ (self, i) Implements item creation/update
del c[i] __delitem__ (self, i) Implements item removal
x(arg, ...) __call__ (self, arg, ...) Implements the call operator
len(c) __len__ (self) Implements len()
x in c
x not in c
__contains__ (self, other) Implements in operator
class() __init__ (self, ...) Instance constructor; called when the class is created
del x __del__ (self) Instance destructor; called just before being deallocated
repr(x)
-- or --
`x`
__repr__(self) Implements repr() on this class
str(x) __str__(self) Implements str() on this class; Jython uses __repr__ if __str__ is not defined. str() is used like x.toString() in Java

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.


Appendix C: Jython debugger commands

The debugger provides the following functions/features:

Command Arguments Function
h, help -- none -- List the available commands
w, where -- none -- Shows the current stack trace
d, down -- none -- Move down one stack frame
u, up -- none -- Move up one stack frame
b, break line# | function, condition_expr Set a breakpoint at a line number or function with an optional expression to evaluate - stop only if true
tbreak line# | function, condition_expr Set a breakpoint at a line number or function with an optional expression to evaluate - stop only if true; the breakpoint is automatically cleared when hit
cl, clear bpid... Clears all or listed breakpoints
enable bpid... Enables breakpoints
disable bpid... Disabled breakpoints
ignore bpid, count Sets the breakpoint ignore (auto-resume) count
condition bpid, condition_expr Sets the breakpoint condition expression
s, step -- none -- Steps over the next line, possibly into a function
n, next -- none -- Resume until the next line is reached
r, return -- none -- Resume until the current function returns
c, cont, continue -- none -- Resume execution
j, jump line# Set a new current line
l, list line#1, line#1 Lists source from line#1 to line#2, if omitted, then list the lines around the current line
a, args -- none -- Show the arguments of the current function
p, pp expr Evaluate the expression and print its result; pp formats the result
print expr Do the print statement, that is, - !print expr
alias name, expr Create a named expression to simplify printing of repeated values
unalias name Delete an alias
q, quit -- none -- End the debugging session
! statement Execute the Jython statement

Note: entering a blank line repeats the prior command.


Appendix D: Jython to/from Java type mapping

Jython uses these rules to map parameter types:

Java Parameter Types Allowed Python Types
char String (must have length 1)
Boolean Integer (true = nonzero)
byte, short, int, long Integer
float, double Float
java.lang.String, byte[], char[] String
java.lang.Class Class or JavaClass
Foobar[] Array (must contain objects of class or subclass of Foobar)
java.lang.Object String->java.lang.String, all others unchanged
org.python.core.PyObject All unchanged
Foobar Instance --> Foobar (if Instance is subclass of Foobar); JavaInstance --> Foobar (if JavaInstance is instance of Foobar or subclass)

Jython uses these rules to map return value types:

Java Return Type Returned Python Type
char String (of length 1)
Boolean Integer (true = 1, false = 0)
byte, short, int, long Integer
float, double Float
java.lang.String String
java.lang.Class JavaClass which represents given Java class
Foobar[] Array (containing objects of class or subclass of Foobar)
org.python.core.PyObject (or subclass) Unchanged
Foobar JavaInstance which represents the Java Class Foobar

Note: the above two tables are from the www.jython.org site.


Appendix E: The sys module

The sys module has some important variables:

Variable Comment(s)
argv The arguments supplied to the main module. argv[0] is the program name, argv[1] is the first argument and so on
maxint
minint
Largest/smallest integer value
platform The version of Java Jython is running on
path The module search path
stdin
stdout
stderr
Standard input, output and error streams
modules List of currently loaded modules
version
version_info
Jython version and details

The sys module has some important functions:

Function Comment(s)
exit(int) Exits the program
exc_info() Get information on the most recent exception

See the Python Library Reference for more information.


Appendix F: The os module

The os module has some important variables:

Variable Comment(s)
name Type of host
curdir String to represent the current directory
pardir String to represent the parent directory
sep String to separate directories in a path
pathsep String to separate paths in a path set string
linesep String to separate text lines
environ The current environment string

The sys module has some important functions:

Function Comment(s)
getcwd() Get the current directory
mkdir(path)
makedirs(path)
rmdir(path)
Create/delete a directory
remove(path)
-- or --
unlink(path)
Delete a file
listdir(path) List the files in a path
rename(path, new) Renames a file/directory to new
system(command) Run a shell command

See the Python Library Reference for more information.


Appendix G: The os.path module

The os.path module has some important functions:

Function Comment(s)
exists(path) True is path exists
abspath(path)
normpath(path)
normcase(path)
Returns the absolute form of the path
Returns the normalized form of the path
Returns the path in the normal case
basename(path)
dirname(path)
Returns the file part of path
Returns the directory part of path
commonprefix(list) Returns the longest common prefix of the paths in the list
gethome() Gets the home directory
getsize(path) Gets the size of the path file
isabs(path)
isfile(path)
isdir(path)
Tests to see if path is absolute
Tests to see if path is a file
Tests to see if path is a dir
samepath(path1, path2) True if path1 and path2 represent the same file
join(list) Joins the path elements in the list
split(path)
splitdrive(path)
splitext(path)
Returns (path, last_element)
Returns (drive, rest_of_path)
Returns (root, extension)

See the Python Library Reference for more information.


Appendix H: Regular expression control characters

The most useful Regular Expression special characters are:

Special Notation Comment(s)
Any character except those below Matches that character
. Matches any character
^ Matches the start of the string
$ Matches the end of the string
?
??
Matches longest 0 or 1 of the proceeding
Matches shortest 0 or 1 of the proceeding
+
+?
Matches longest 1 or more of the proceeding
Matches shortest 1 or more of the proceeding
*
*?
Matches longest 0 or more of the proceeding
Matches shortest 0 or more of the proceeding
{m,n}
{m,n}?
Matches longest m to n of the proceeding
Matches shortest m to n of the proceeding
[...]
[^...]
Defines the set of enclosed characters
Defines the set of non-enclosed characters
...|... Matches a choice (or)
(...)
(?...)
Matches the sequence (or group) ...; groups are ordered from left to right with origin 1
Matches a sequence but does not define a group
(?P<name>...)
(?P=name)
Matches a sequence (or group) ... giving it a name
Matches the sequence defined with the name
(?=...)
(?!...)
Matches ... but does not consume the test
Matches not ... but does not consume the test
\c Special characters:
\c literal escapes: .?*+&^$|()[]
\c function escapes: see below

See the Python Library Reference for more information.

Function escapes:

Function Escapes Comment(s)
\A
\Z
Matches at start of line
Matches at end of line
\B
\b
Matches not at beginning or end of a word
Matches at beginning or end of a word
\D
\d
Matches not any decimal digit (0..9)
Matches any decimal digit (0..9)
\S
\s
Matches not any white space
Matches any white space
\W
\w
Matches not any alpha-numeric characters
Matches any alpha-numeric characters
\# 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
Match ignoring case
MULTILINE
-- or --
M
Causes '^' and '$' to match internal line boundaries (vs. just the start and end of the string)
DOTALL
-- or --
S
Causes '.' to match a newline

Appendix I: Generated factor.java

The following is the code generated by jythonc compiler for the factor.py file of The factorial engine: factor.py.

import org.python.core.*;

public class factor extends java.lang.Object {
     static String[] jpy$mainProperties =
         new String[] {"python.modules.builtin",
                       "exceptions:org.python.core.exceptions"};

     static String[] jpy$proxyProperties =
         new String[] {"python.modules.builtin",
                       "exceptions:org.python.core.exceptions",
                       "python.options.showJavaExceptions",
                       "true"};

     static String[] jpy$packages = new String[] {};

     public static class _PyInner extends PyFunctionTable
            implements PyRunnable {
         private static PyObject i$0;
         private static PyObject i$1;
         private static PyObject s$2;
         private static PyObject l$3;
         private static PyObject i$4;
         private static PyObject s$5;
         private static PyObject s$6;
         private static PyObject s$7;
         private static PyObject s$8;
         private static PyObject s$9;
         private static PyObject i$10;
         private static PyObject i$11;
         private static PyObject s$12;
         private static PyFunctionTable funcTable;
         private static PyCode c$0___init__;
         private static PyCode c$1_addListener;
         private static PyCode c$2_addListeners;
         private static PyCode c$3_removeListener;
         private static PyCode c$4_removeListeners;
         private static PyCode c$5_fireListeners;
         private static PyCode c$6_cancel;
         private static PyCode c$7_calculate;
         private static PyCode c$8_Factorial;
         private static PyCode c$9_doFac;
         private static PyCode c$10_main;
         private static void initConstants() {
             i$0 = Py.newInteger(0);
             i$1 = Py.newInteger(1);
             s$2 = Py.newString("only positive integers supported: ");
             l$3 = Py.newLong("1");
             i$4 = Py.newInteger(100);
             s$5 = Py.newString("__main__");
             s$6 = Py.newString("running...");
             s$7 = Py.newString("For");
             s$8 = Py.newString("result =");
             s$9 = Py.newString("Exception -");
             i$10 = Py.newInteger(10);
             i$11 = Py.newInteger(1000);
             s$12 = Py.newString("C:\\Articles\\factor.py");
             funcTable = new _PyInner();
             c$0___init__ = Py.newCode(1, new String[] {"self"},
                                       "C:\\Articles\\factor.py",
                                       "__init__", false, false,
                                       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,
                                          null, null, 0, 0);
             c$9_doFac = Py.newCode(1,
                                          new String[]
                                          {"value", "e"},
                                          "C:\\Articles\\factor.py",
                                          "doFac", false,
                                          false, funcTable, 9,
                                          null, null, 0, 1);
             c$10_main = Py.newCode(0,
                                          new String[] {},
                                          "C:\\Articles\\factor.py",
                                          "main", false,
                                          false, funcTable, 10,
                                          null, null, 0, 0);
         }


         public PyCode getMain() {
             if (c$10_main == null) _PyInner.initConstants();
             return c$10_main;
         }

         public PyObject call_function(int index, PyFrame frame) {
             switch (index){
                 case 0:
                 return _PyInner.__init__$1(frame);
                 case 1:
                 return _PyInner.addListener$2(frame);
                 case 2:
                 return _PyInner.addListeners$3(frame);
                 case 3:
                 return _PyInner.removeListener$4(frame);
                 case 4:
                 return _PyInner.removeListeners$5(frame);
                 case 5:
                 return _PyInner.fireListeners$6(frame);
                 case 6:
                 return _PyInner.cancel$7(frame);
                 case 7:
                 return _PyInner.calculate$8(frame);
                 case 8:
                 return _PyInner.Factorial$9(frame);
                 case 9:
                 return _PyInner.doFac$10(frame);
                 case 10:
                 return _PyInner.main$11(frame);
                 default:
                 return null;
             }
         }

         private static PyObject __init__$1(PyFrame frame) {
             frame.getlocal(0).__setattr__("_Factorial__listeners",
                            new PyList(new PyObject[] {}));
             frame.getlocal(0).__setattr__("_Factorial__cancelled", i$0);
             return Py.None;
         }

         private static PyObject addListener$2(PyFrame frame) {
             frame.setlocal(2,
                  frame.getlocal(0).__getattr__("_Factorial__listeners"));
             if (frame.getlocal(1)._notin(
                    frame.getlocal(2) ).__nonzero__()) {
                 frame.getlocal(2).invoke("append", frame.getlocal(1));
             }
             return Py.None;
         }

         private static PyObject addListeners$3(PyFrame frame) {
             // Temporary Variables
             int t$0$int;
             PyObject t$0$PyObject, t$1$PyObject;

             // Code
             t$0$int = 0;
             t$1$PyObject = frame.getlocal(1);
             while ((t$0$PyObject =
                    t$1$PyObject.__finditem__(t$0$int++)) != null) {
                 frame.setlocal(2, t$0$PyObject);
                 frame.getlocal(0).invoke("addListener",
                     frame.getlocal(2));
             }
             return Py.None;
         }

  
                

                       private static PyObject removeListener$4(PyFrame frame) {
             frame.setlocal(2,
    frame.getlocal(0).__getattr__("_Factorial__listeners"));
             frame.getlocal(2).invoke("remove", frame.getlocal(1));
             return Py.None;
         }

         private static PyObject removeListeners$5(PyFrame frame) {
             // Temporary Variables
             int t$0$int;
             PyObject t$0$PyObject, t$1$PyObject;

             // Code
             t$0$int = 0;
             t$1$PyObject = frame.getlocal(1);
             while ((t$0$PyObject =
     t$1$PyObject.__finditem__(t$0$int++)) != null) {
                 frame.setlocal(2, t$0$PyObject);
                 frame.getlocal(0).invoke("removeListener",
                        frame.getlocal(2));
             }
             return Py.None;
         }

         private static PyObject fireListeners$6(PyFrame frame) {
             // Temporary Variables
             int t$0$int;
             PyObject t$0$PyObject, t$1$PyObject;

             // Code
             t$0$int = 0;
             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));
                         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);
                     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"});
     }

}

Note: The above code has been reformatted for line length.


Appendix J: Formatting strings and values

Note that a simplified form of Appendix J originally appeared as multiple panels in Part 1 of this tutorial.

Jython strings support a special formating operation similar to C's printf, but using the modulo ("%") operator. The right-hand set of items is substituted into the left-hand string at the matching %x locations in the string. The set value is usually a single value, a tuple of values, or a dictionary of values.

The general format of the format specification is

    %{(key)}{flag}...{width}{.precision}x
          

Here's a guide to the format items:

  • key: Optional key to lookup in a supplied dictionary

  • flag: Optional flags (reasonable combinations supported)
    • #: Display any special format prefix (for example, "0" for octal, "0x" for hex)

    • +: Display a "+" on positive numbers

    • blank: Display a leading space on positive numbers

    • -: Left (vs. right) justify the value in the width

    • 0: Left pad with "0" (vs. spaces)
  • width: Minimum width of the field (will be longer for large values)

  • precision: Number of digits after any decimal point

  • x: Format code as described below

The format operator supports the following format characters:

Character(s) Result Format Comment(s)
%s, %r String %s does str(x), %r does repr(x)
%i, %d Integer Decimal Basically the same format
%o, %u, %x, %X Unsigned Value In octal, unsigned decimal, hexadecimal
%f, %F Floating Decimal Shows fraction after decimal point
%e, %E, %g, %G Exponential %g is %f unless the value is small; else %e
%c Character Must be a single character or integer
%% Character The % character

Note: more details on the structure and options of the format item can be found in the Python Library Reference (Resources). Use of case in format characters (for example, X vs x causes the symbol to show in matching case.

For example

print "%s is %i %s %s than %s!" % ("John", 5, "years", "older", "Mark")

print "Name: %(last)s, %(first)s" % \
	{'first':"Barry", 'last':"Feigenbaum", 'age':18}

prints

John is 5 years older than Mark!
Name: Feigenbaum, Barry


Appendix K: Built-in functions

Note that Appendix K appeared in Part 1 of this tutorial.

Jython provides very useful built-in functions that can be used without any imports. The most commonly used ones are summarized below:

Syntax Use/Comment(s) Example(s)
abs(x) Absolute value abs(-1) --> 1
apply(func, pargs {, kargs})
-- or --
func(*pargs {, **kargs})
Execute the function with the supplied positional arguments and optional keyword arguments apply(lambda x, y: x * y, (10, 20)) --> 200
callable(x) Tests to see if the object is callable (i.e, is a function, class or implements __call__) callable(MyClass) --> 1
chr(x) Converts the integer (0 - 65535) to a 1-character string chr(9) --> "\t"
cmp(x, y) Compares x to y: returns: negative if x < y; 0 if x == y; positive if x > y cmp("Hello", "Goodbye") --> > 0
coerce(x, y) Returns the tuple of x and y coerced to a common type coerce(-1, 10.2) --> (-1.0, 10.2)
compile(text, name, kind) Compile the text string from the source name. Kind is: "exec", "eval" or "single"
x = 2
c = compile("x * 2",
             "<string>", "eval")
eval(c) --> 4

complex(r, i) Create a complex number complex(1, 2) --> 1.0+2.0j
complex("1.0-0.1j") --> 1.0-0.1j
dir({namespace}) Returns a list of the keys in a namespace (local if omitted) dir() --> [n1, ..., nN]
vars({namespace}) Returns the namespace (local if omitted); do not change it vars() --> {n1:v1, ..., nN:vN}
divmod(x, y) Returns the tuple (x /y, x % y) divmod(100, 33) --> (3, 1)
eval(expr {, globals {, locals}}) Evaluate the expression in the supplied namespaces
myvalues = {'x':1, 'y':2}
eval("x + y", myvalues) --> 3

execfile(name {,globals {, locals}}) Read and execute the named file in the supplied namespaces execfile("myfile.py")
filter(func, list) Creates a list of items for which func returns true filter(lambda x: x > 0, [-1, 0, 1, -5, 10]) --> [1, 10]
float(x) Converts x to a float float(10) --> 10.0
float("10.3") --> 10.3
getattr(object, name {, default}) Gets the value of the object's attribute; if not defined return default (or an exception if no default) getattr(myObj, "size", 0) --> 0
setattr(object, name, value) Creates/sets the value of the object's attribute setattr(myObj, "size", 10)
hasattr(object, name) Test to see if the object has an attribute hasattr(myObj, "size") --> 0
globals() Returns the current global namespace dictionary {n1:v1, ..., nN:vN}
locals() Returns the current local namespace dictionary {n1:v1, ..., nN:vN}
hash(object) Returns the object's hash value. Similar to java.lang.Object.hashCode() hash(x) --> 10030939
hex(x) Returns a hex string of x hex(-2) --> "FFFFFFFE"
id(object) Returns a unique stable integer id for the object id(myObj) --> 39839888
input(prompt) Prompts and evaluates the supplied input expression; equivalent to eval(raw_input(prompt)) input("Enter expression:")
with "1 + 2" --> 3
raw_input(prompt) Prompts for and inputs a string raw_input("Enter value:")
with "1 + 2" --> "1 + 2"
int(x{, radix}) Converts to an integer; radix: 0, 2..36; 0 implies guess int(10.2) --> 10
int("10") --> 10
int("1ff", 16) --> 511
isinstance(object, class) Tests to see if object is an instance of class or a subclass of class; class may be a tuple of classes to test multiple types isinstance(myObj, MyObject) --> 0
isinstance(x, (Class1, Class2)) --> 1
issubclass(xclass, clsss) Tests to see if xclass is a sub-(or same) class of class; class may be a tuple of classes to test multiple types issubclass(MyObject, (Class1, Class2)) --> 0
len(x) Returns the length (number of items) in the sequence or map len("Hello") --> 5
list(seq) Converts the sequence into a list list((1, 2, 3)) --> [1,2,3]
list("Hello") --> ['H','e','l','l','o']
tuple(seq) Converts the sequence into a tuple tuple((1, 2, 3)) --> (1,2,3) tuple("Hello")--> ('H','e','l','l','o')
long(x {, radix}) Converts to a long integer; radix: 0, 2..36; 0 implies guess long(10) --> 10L
long("10000000000") -->
10000000000L
map(func, list, ...) Creates a new list from the results of applying func to each element of each list map(lambda x,y: x+y, [1,2],[3,4]) --> [4,6]
map(None, [1,2],[3,4]) --> [[1,3],[2,4]]
max(x) Returns the maximum value max(1,2,3) --> 3
max([1,2,3]) --> 3
min(x) Returns the minimum value min(1,2,3) --> 1
min([1,2,3]) --> 1
oct(x) Converts to an octal string oct(10) --> "012
oct(-1) --> "037777777777"
open(name, mode {, bufsize}) Returns an open file. Mode is:(r|w|a){+}{b} open("useful.dat", "wb", 2048)
ord(x) Returns the integer value of the character ord('\t') --> 9
pow(x,y)
pow(x,y,z)
Computes x ** y
Computes x ** y % z
pow(2,3) --> 8
range({start,} stop {, inc})
xrange({start,} stop {, inc})
Returns a sequence ranging from start to stop in steps of inc; start defaults to 0; inc defaults to 1. Use xrange for large sequences (say more than 20 items) range(10) --> [0,1,2,3,4,5,6,7,8,9]
range(9,-1,-1) --> [9,8,7,6,5,4,3,2,1,0]
reduce(func, list {, init}) Applies func to each pair of items in turn accumulating a result reduce(lambda x,y:x+y, [1,2,3,4],5) --> 15
reduce(lambda x,y:x&y, [1,0,1]) --> 0
reduce(None, [], 1) --> 1
repr(object)
-- or --
`object`
Convert to a string from which it can be recreated, if possible repr(10 * 2) --> "'20'"
repr('xxx') --> "'xxx'"
x = 10; `x` --> "10'"
round(x {, digits}) Rounds the number round(10.009, 2) --> 10.01
round(1.5) --> 2
str(object) Converts to human-friendly string str(10 * 2) --> "20"
str('xxx') --> 'xxx'
type(object) Returns the type (not the same as class) of the object. To get the class use object.__class__. Module types has symbolic names for all Jython types x = "1"; type(x) is type('') --> 1
zip(seq, ...) Zips sequences together; results is only as long as the shortest input sequence zip([1,2,3],"abc") --> [(1,'a'),(2,'b'),(3,'c')]

See the Python Library Reference (Resources) for more details.


Appendix L: Jython types summary

Note that Appendix L appeared in Part 1 of this tutorial.

Jython supports many object types. The module types defines symbols for these types. The function type gets the type of any object. The type value can be tested (see ). The table below summarizes the most often used types.

Type symbol Jython runtime type Comment(s)
ArrayTypePyArrayAny array object
BuiltinFunctionTypePyReflectedFunctionAny built-in function object
BuiltinMethodTypePyMethodAny built-in method object
ClassTypePyClassAny Jython class object
ComplexTypePyComplexAny complex object
DictType
-- or --
DictionaryType
PyDictionaryAny dictionary object
FileTypePyFileAny file object
FloatTypePyFloatAny float object
FunctionTypePyFunctionAny function object
InstanceTypePyInstanceAny class instance object
-- none --PyJavaInstanceAny Java class instance object
IntTypePyIntegerAny integer object
LambdaTypePyFunctionAny lambda function expression object
ListTypePyListAny list object
LongTypePyLongAny long object
MethodTypePyMethodAny non-built-in method object
ModuleTypePyModuleAny module object
NoneTypePyNoneAny None (only one) object
StringTypePyStringAny ASCII string object
TracebackTypePyTracebackAny exception traceback object
TupleTypePyTupleAny tuple object
TypeTypePyJavaClassAny type object
UnboundMethodTypePyMethodAny method (without a bound instancee) object
UnicodeTypePyStringAny Unicode string object
XRangeTypePyXRangeAny extended range object

Note: several types map to the same Java runtime type. For more information on types see the Python Library Reference (Resources).

13 of 15 | Previous | Next

Comments



Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Java technology
ArticleID=131936
TutorialTitle=Introduction to Jython, Part 2: Programming essentials
publish-date=04082004
author1-email=feigenba@us.ibm.com
author1-email-cc=jaloi@us.ibm.com

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere).

My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).