Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling python module from Java

Tags:

java

python

I want to call a function from a python module from Java using "PythonInterpreter" and here's my Java code

PythonInterpreter interpreter = new PythonInterpreter();

interpreter.exec("import sys\nsys.path.append('C:\\Python27\\Lib\\site-packages')\nimport helloworld");

PyObject someFunc = interpreter.get("helloworld.getName");

PyObject result = someFunc.__call__();

String realResult = (String) result.__tojava__(String.class);

System.out.println(realResult);

and the Python code (helloworld.py) is below:

    from faker import Factory
    fake = Factory.create()

    def getName():
       name = fake.name()
       return name  

The problem I'm facing is while I'm calling interpreter.get when it returns a null PyObject.

Any idea what's going wrong? The python code runs fine from IDLE

EDIT

I just did a bit of change in the code as below

PythonInterpreter interpreter = new PythonInterpreter();

interpreter.exec("import sys\nsys.path.append('C:\\Python27\\Lib\\site-packages')\nimport helloworld");


PyInstance wrapper = (PyInstance)interpreter.eval("helloworld" + "(" + ")");  

PyObject result = wrapper.invoke("getName()");

String realResult = (String) result.__tojava__(String.class);

System.out.println(realResult);

and I introduced a class in my python module

from faker import Factory

class helloworld:

def init(self):
    fake = Factory.create()

def getName():
    name = fake.name()
    return name 

Now am getting the error below

Exception in thread "main" Traceback (innermost last):
  File "<string>", line 1, in ?
TypeError: call of non-function (java package 'helloworld')
like image 623
user1356042 Avatar asked Mar 27 '14 19:03

user1356042


1 Answers

  1. You cannot use python attribute access in PythonInterpreter.get. Just use attribute name to get the module, and retrieve attribute from it.
  2. (EDIT PART) Python code is totally broken. Please see the proper example below. And, of course, www.python.org.
  3. (EDIT PART) First parameter of PyInstance.invoke should be method name.
  4. Below you can find working code sample for both cases

Main.java

import org.python.core.*;
import org.python.util.PythonInterpreter;

public class Main {

    public static void main(String[] args) {
        test1();
        test2();
    }

    private static void test1() {
        PythonInterpreter interpreter = new PythonInterpreter();
        interpreter.exec("import hello_world1");
        PyObject func = interpreter.get("hello_world1").__getattr__("get_name");
        System.out.println(func.__call__().__tojava__(String.class));
    }

    private static void test2() {
        PythonInterpreter interpreter = new PythonInterpreter();
        interpreter.exec("from hello_world2 import HelloWorld");
        PyInstance obj = (PyInstance)interpreter.eval("HelloWorld()");
        System.out.println(obj.invoke("get_name").__tojava__(String.class));
    }
}

hello_world1.py

def get_name():
    return "world"

hello_world2.py

class HelloWorld:
    def __init__(self):
        self.world = "world"

    def get_name(self):
        return self.world
like image 146
apatrushev Avatar answered Oct 07 '22 07:10

apatrushev