26.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.
26.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 in "The PyObject Class" on page 661. The most frequently used methods and overloads of a PythonInterpreter instance interp are the following.
126.96.36.199. The _ _builtin_ _ class
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 compile on page 160. 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 those covered in "Compile and Code Objects" on page 329.
26.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 that wraps 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 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 boil 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 >= L, and the last L items of args are taken as named arguments, the names being the corresponding items in keywords. When args has length N > 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 instantiate such 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 .
26.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 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 PyObject argument and return the corresponding value of the given primitive Java type.