alibaba / pemja

Apache License 2.0
91 stars 26 forks source link

Generic invokeMethod #22

Open Robbie-Palmer opened 2 years ago

Robbie-Palmer commented 2 years ago

It would be great if invokeMethod could take the return type, similar to public <T> T get(String name, Class<T> clazz)

The below code which passes an integer to Python and expects an integer back fails with the error class java.lang.Long cannot be cast to class java.lang.Integer

var pyFnName = "add_one";
var pythonCode = pyFnName + " = lambda x: x + 1";
int input = 5;
try (var interpreter = new PythonInterpreter(config);) {
    interpreter.exec(pythonCode);
    var pyFn = (PyObject) interpreter.get(pyFnName);
    var out = (int) pyFn.invokeMethod("__call__", input);
    System.out.println(out);
}

An integer can be retrieved by using the generic get alongside exec but is fiddlier and less pretty

var pyFnName = "add_one";
var pythonCode = pyFnName + " = lambda x: x + 1";
int input = 5;
try (var interpreter = new PythonInterpreter(config);) {
    interpreter.exec(pythonCode);
    var resultVarName = "result";
    interpreter.exec(resultVarName + "=" + pyFnName + "(" + input + ")");
    var out = (int) interpreter.get(resultVarName, Integer.class);
    System.out.println(out);
}

Or can accept the value back as a Long and convert it to an int value

var out = (Long) pyFn.invokeMethod("__call__", input);
var intOut = out.intValue();

So functionally everything is available, with a public <T> T invokeMethod(String name, Class<T> clazz, Object... args) method just providing syntactic sugar

HuangXingBo commented 2 years ago

@Robbie-Palmer I thinks it is a good optimization for usage.