25.2 Embedding Jython in Java
Your Java-coded application can embed
the Jython interpreter in order to use Jython for scripting.
jython.jar must be in your Java
CLASSPATH. Your Java code must import
org.python.core.* and
org.python.util.* in order to access
Jython's classes. To initialize
Jython's state and instantiate an interpreter, use
the Java statements:
PySystemState.initialize( );
PythonInterpreter interp = new PythonInterpreter( );
Jython also supplies several advanced overloads of this method and
constructor in order to let you determine in detail how
PySystemState is set up, and to control the system
state and global scope for each interpreter instance. However, in
typical, simple cases, the previous Java code is all your application
needs.
25.2.1 The PythonInterpreter Class
Once you have an instance
interp of class
PythonInterpreter, you can call method
interp.eval to have the
interpreter evaluate a Python expression held in a Java string. You
can also call any of several overloads of
interp.exec and
interp.execfile to have
the interpreter execute Python statements held in a Java string, a
precompiled Jython code object, a file, or a Java
InputStream.
The Python code you execute can import your Java
classes in order to access your application's
functionality. Your Java code can set attributes in the interpreter
namespace by calling overloads of
interp.set, and get
attributes from the interpreter namespace by calling overloads of
interp.get. The
methods' overloads give you a choice. You can work
with native Java data and let Jython perform type conversions, or you
can work directly with PyObject, the base class of
all Python objects, covered later in this chapter. The most
frequently used methods and overloads of a
PythonInterpreter instance
interp are the following.
PyObject interp.eval(String s)
|
|
Evaluates, in interp's
namespace, the Python expression held in Java string
s, and returns the
PyObject that is the expression's
result.
void interp.exec(String s)
void interp.exec(PyObject code)
|
|
Executes, in interp's
namespace, the Python statements held in Java string
s or in compiled
PyObject code (produced
by function _ _builtin_ _.compile of package
org.python.core, covered later in this chapter).
void interp.execfile(String name)
void interp.execfile(java.io.InputStream s)
void interp.execfile(java.io.InputStream s,String name)
|
|
Executes, in interp's
namespace, the Python statements read from the stream
s or from the file named
name. When you pass both
s and name,
execfile reads the statements from
s, and uses
name as the filename in error messages.
PyObject interp.get(String name)
Object interp.get(String name,Class javaclass)
|
|
Fetches the value of the attribute named
name from
interp's namespace. The
overload with two arguments also converts the value to the specified
javaclass, throwing a Java
PyException exception that wraps a Python
TypeError if the conversion is unfeasible. Either
overload raises a NullPointerException if
name is unbound. Typical use of the
two-argument form might be a Java statement such as:
String s = (String)interp.get("attname", String.class);
void interp.set(String name,PyObject value)
void interp.set(String name,Object value)
|
|
Binds the attribute named name in
interp's namespace to
value. The second overload also converts
the value to a PyObject.
The org.python.core
package supplies a class _ _builtin_ _ whose
static methods let your Java code access the functionality of Python
built-in functions. The compile method, in
particular, is quite similar to Python built-in function
compile, covered in Chapter 8 and Chapter 13. Your Java
code can call compile with three
String arguments (a string of source code, a
filename to use in error messages, and a
kind that is normally
"exec"), and compile returns a
PyObject instance p
that is a precompiled Python bytecode object. You can repeatedly call
interp.exec(p)
to execute the Python statements in p
without the overhead of compiling the Python source for each
execution. The advantages are the same as covered in Chapter 13.
25.2.2 The PyObject Class
Seen from Java, all Jython objects are
instances of classes that extend PyObject. Class
PyObject supplies methods named like Python
objects' special methods, such as _ _len_
_, _ _str_ _, and so on. Concrete
subclasses of PyObject override some special
methods to supply meaningful implementations. For example, _
_len_ _ makes sense for Python sequences and mappings, but
not for numbers; _ _add_ _ makes sense for numbers
and sequences, but not for mappings. When your Java code calls a
special method on a PyObject instance that does
not in fact supply the method, the call raises a Java
PyException exception wrapping a Python
AttributeError.
PyObject methods that set, get, and delete
attributes exist in two overloads, as the attribute name can be a
PyString or a Java String.
PyObject methods that set, get, and delete items
exist in three overloads, as the key or index can be a
PyObject, a Java String, or an
int. The Java String instances
that you use as attribute names or item keys must be Java interned
strings (i.e., either string literals or the result of calling
s.intern( ) on any Java
String instance s). In
addition to the usual Python special methods _ _getattr_
_ and _ _getitem_ _, class
PyObject also provides similar methods _
_findattr_ _ and _ _finditem_ _, the
difference being that, when the attribute or item is not found, the
_ _find methods return a Java
null, while the _ _get methods
raise exceptions.
Every PyObject
instance p has a method _
_tojava_ _ that takes a single argument, a Java
Class c, and returns an
Object that is the value of
p converted to
c (or raises an exception if the
conversion is unfeasible). Typical use might be a Java statement such
as:
String s = (String)mypyobj._ _tojava_ _(String.class);
Method _
_call_ _ of PyObject has several
convenience overloads, but the semantics of all the overloads come
down to _ _call_ _'s fundamental
form:
PyObject p._ _call_ _(PyObject args[], String keywords[]);
When array keywords has length
L, array args
must have length N greater than or equal
to L, and the last
L items of args
are taken as named actual arguments, the names being the
corresponding items in keywords. When
args has length
N greater than
L,
args's first
N-L
items are taken as positional actual arguments. The equivalent Python
code is therefore similar to:
def docall(p, args, keywords):
assert len(args) >= len(keywords)
deltalen = len(args) - len(keywords)
return p(*args[:deltalen], ** dict(zip(keywords, args[deltalen:])))
Jython supplies concrete subclasses of PyObject
that represent all built-in Python types. You can sometimes usefully
instantiate a concrete subclass in order to create a
PyObject for further use. For example, class
PyList extends PyObject,
implements a Python list, and has constructors that take an array or
a java.util.Vector of PyObject
instances, as well as an empty constructor that builds the empty list
[].
25.2.3 The Py Class
The Py class supplies
several utility class attributes and static methods.
Py.None is Python's
None. Method Py.java2py takes a
single Java Object argument and returns the
corresponding PyObject. Methods
Py.py2type, for all
values of type that name a Java primitive
type (boolean, byte,
long, short, etc.), take a
single PyObject argument and return the
corresponding value of the given primitive Java type.
|