user1356042
user1356042

Reputation: 385

Calling python module from Java

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')

Upvotes: 10

Views: 13318

Answers (1)

apatrushev
apatrushev

Reputation: 425

  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

Upvotes: 5

Related Questions