Home > Articles > Programming > Java

Extending Jython

  • Print
  • + Share This
From the author of

Parameters

Jython functions benefit from a rich parameter scheme that includes ordered parameter, keyword parameters, default values, and wild cards. It is possible to emulate this behavior in Java. The following method signature allows a Java method to handle positional and keyword arguments:

public PyObject MyFunction(PyObject[] args, String[] kw); 

The args array holds all argument values, whereas the kw array holds only the specified keys. The following is an example call of the previously mentioned MyFunction:

MyFunction(1, 2, D=4, C=9)

The args and kw arrays would then look like the following:

args = [1, 2, 4, 9]
kw = ["D", "C"]

Using these values requires some parsing, and the class org.python.core.ArgParser eases parsing these parameters into more useful forms. The ArgParser class has four constructors:

public ArgParser(String funcname, PyObject[] args,
         String[] kws, String p0)

public ArgParser(String funcname, PyObject[] args,
         String[] kws, String p0, String p1)

public ArgParser(String funcname, PyObject[] args,
         String[] kws, String p0, String p1, String p2)

public ArgParser(String funcname, PyObject[] args,
         String[] kws, String[] paramnames)

Each constructor requires the function's name as the first parameter. The function using ArgsParser should use the parameters PyObject[] args and String[] kw. These two objects become the second and third arguments to the ArgParser constructor. The remaining parameters are the list of arguments expected by a function. These can be separate args if there are three or fewer; otherwise, they are a String[]. Listing 1 shows a Java method that implements Jython's argument style with the help of ArgParser. Some example Jython methods and their Java method plus ArgParser counterparts are presented here to clarify:

Jython Method:
def test(A, B, C=2)

Java implementation:
public static PyObject test(PyObject[] args, String[] kws) {
  ArgParser ap = new ArgParser("test", args, kws, "A", "B", "C");
}

Jython Method:
def addContact(name, addr, ph=None)

Java implementation:
public static PyObject addContact(PyObject[] args, String[] kws) {
  ArgParser ap = new ArgParser("addContact", args, kws,
                 new String[] {"name", "addr", "ph"});
}

The parameter values are retrieved from the ArgParser instance with one of its get* methods. The get* methods listed here have either one or two parameters. Those with two parameters retrieve parameters with default values. Note that the position of the argument (pos) starts with position 0, not 1.

public String getString(int pos)

public String getString(int pos, String def)

public int getInt(int pos)

public int getInt(int pos, int def)

public PyObject getPyObject(int pos)

public PyObject getPyObject(int pos, PyObject def)

public PyObject getList(int pos)

For the Jython method:

def test(A, B, C=2)

The Java implementation, which allows for the default value, is this:

public static PyObject test(PyObject[] args, String[] kws) {
  ArgParser ap = new ArgParser("test", args, kws, "A", "B", "C");
  int A = ap.getInt(0);
  // or...
  // String A = ap.getString(0);
  // PyObject A = ap.getPyObject(0);
  // PyTuple A = (PyTuple)ap.getList(0);

  String B = ap.getString(1);
  // or...
  // int B = ap.getInt(1);
  // PyObject B = ap.getPyObject(1);
  // PyObject B = ap.getList(1);

  // here's the two argument version to allow for defaults
  int C = ap.getInt(2, 2);// first 2=position, second 2=default value
}
  • + Share This
  • 🔖 Save To Your Account