How to run Python programs from Java
An easy way to run Python programs from within Java is to invoke
the Jython interpreter to run the Python code.
The Python programs require little or no modification.
Unlike all Java code which must be in OO methods, there is no such requirement
for Python. Procedural Python is fine.
Start by writing and testing your Python program as a Python program.
Then include code, like that shown below, in your Java code. It's quicker
that way.
In following example, main instantiates a Jython interpreter,
loads a value into num, runs sq.py, and extracts and prints
the answer.
(Here everything runs in main, but that is not necessary.)
// file RunSqPy.java
import org.python.util.PythonInterpreter;
import org.python.core.*;
public class RunSqPy {
static public void main(String[] args) throws PyException {
// instantiate the interpreter
PythonInterpreter interp = new PythonInterpreter();
// set runtime args as Jython global variables
interp.set("num", new PyInteger(2));
// cause the Python program to be run (a fully
// qualified pathname is allowed)
interp.execfile("sq.py");
// get values
PyObject sq = interp.get("square");
PyObject num = interp.get("num");
// ...and do with them as you please (you may need
// to cast them depending on usage)
System.out.println("square of " + num + " is " + sq);
}
}
Compile this with javac RunSqPy.java, but before running it, be
sure you have the file sq.py as shown below.
# file: sq.py
# this could be a whole lot more sophisticated, but
# this is sufficient to illustrate how to access
# variables before and after execution.
print '--- sq.py start ---'
if __name__ == '__main__':
num = 7
print 'num =', num
square = num**2
print 'square =', square
print '---- sq.py end ----'
Typing java RunSqPy should yield
--- sq.py start ---
num = 2
square = 4
---- sq.py end ----
square of 2 is 4
but typing python sq.py should give
--- sq.py start ---
num = 7
square = 49
---- sq.py end ----
Remember, only the core Python libraries were ported to Jython.
You will have to make available any other Python modules you need.
Compiling the Java code in Appendix A
(RunPython.java) provides a general purpose Java class to
facilitate the running of Python code.
This cleaner example does the same as RunSqPy.java above.
// file: ShortTestPython.java
import RunPython.*;
public class ShortTestPython {
public static void main(String[] args) {
RunPython py = new RunPython();
py.setInt("num", 2);
py.run("sq.py");
System.out.println("square = " + py.getInt("square"));
}
}
Your Python program might want to have logic that can determine if it is
running standalone (from a command line) or is being called from a Java
program.
A simple declarative technique is
if __name__ == '__main__':
num = 7
If your code needs to run in multiple environments where the value of
a variable can be set set in one of several ways, you will need some way
of detecting whether it has already been set or not. The following
example allows you to not give a value if the variable already
has one.
try: # if not already defined (fm Java), an
junk = num # exception will be thrown
except:
num = 7 # set a default value or inspect the
# command line arguments (sys.argv)
Appendix A: RunPython.java
The use of this Java class, RunPython, is strictly optional, but it
does simplifiy access to the Jython interpreter.
import org.python.util.PythonInterpreter;
import org.python.core.*;
public class RunPython {
// instantiate a fresh interpreter
PythonInterpreter interp = new PythonInterpreter();
// a 'do nothing' constructor
public RunPython() { }
// use this contructor if no variables to be passed
// in and you want to run a Jython program (saves a line)
public RunPython(String filename) {
run(filename);
}
// run the named Jython program
public void run(String filename){
interp.execfile(filename);
}
// gets an integer return value
public int getInt(String name) {
return ((PyInteger) interp.get(name)).getValue();
}
// sets an input integer value
public void setInt(String name, int value){
interp.set(name, new PyInteger(value));
}
// gets a double return value (Python floats are doubles)
public double getDouble(String name) {
return ((PyFloat) interp.get(name)).getValue();
}
// sets an input double value (Python floats are doubles)
public void setDouble(String name, double value){
interp.set(name, new PyFloat(value));
}
// gets a string return value
public String getStr(String name) {
return ((PyString) interp.get(name)).toString();
}
// sets an input string value
public void setStr(String name, String value){
interp.set(name, new PyString(value));
}
// can add more getters and setters for complex,
// list, dictionary, tuple, etc. ...someday.
}
Appendix B: Jython References
An excellent book devoted entirely to Jython is "Jython Essentials" by
Pedroni and Rappin, published by O'Reilly
(ISBN 0596002475).
Mark Lutz devoted a section to Jpython (Jython) in his book "Programming
Python", also published by O'Reilly
(ISBN 0596158106).
"The Quick Python Book" also has a section about Jpython. The 1st edition
was written by Harms and McDonald; the 2nd edition is by Ceder and Jones.
(ISBN 193518220X).
"The Definitive Guide to Jython" is a free, open source, Creative Commons
online book. It is also available in hard copy.
(ISBN 1430225270).
And, there is some good information at the
Jython web site.