java调用python文件之第三方包路径

没有用java调用过python的同学,可以先查看如下文章:

http://www.cnblogs.com/u0mo5/p/4032452.html

http://blog.csdn.net/ztf312/article/details/51338060#

http://blog.csdn.net/thorny_v/article/details/61417386

先说一下我的环境:eclipse,jdk1.7,python2.7.8,第三方包:python for arcgis

根据网上资料得知,java调用python脚本约有3种方式:直接执行python脚本、执行脚本文件、Runtime.getRuntime()执行。其中前两个都用的PythonInterpreter


方式一:

直接执行python就不多说了,代码如下:

import javax.script.*;  
  
import org.python.util.PythonInterpreter;  
  
import java.io.*;  
import static java.lang.System.*;  
public class FirstJava  
{  
 public static void main(String args[])  
 {  
    PythonInterpreter interpreter = new PythonInterpreter();  
    interpreter.exec("days=('mod','Tue','Wed','Thu','Fri','Sat','Sun'); ");  
    interpreter.exec("print days[1];");  
 } 
}  

方式二:

执行py文件如下:

首先创建py脚本test.py,定义一个add方法

def add(a,b)
      return a+b

新建java程序执行py脚本

import org.python.core.PyFunction;  
import org.python.core.PyInteger;  
import org.python.core.PyObject;  
import org.python.util.PythonInterpreter; 

public class FirstJava  
{  
    public static void main(String args[])  
    {  
        PythonInterpreter interpreter = new PythonInterpreter();  
        interpreter.execfile("C:\\Python27\\programs\\test.py");  //要执行py脚本的文件路径
        PyFunction func = (PyFunction)interpreter.get("add",PyFunction.class); //py脚本中要执行的方法名称 
  
        int a = 32, b = 23 ;  
        PyObject pyobj = func.__call__(new PyInteger(a), new PyInteger(b)); //给add方法传参数 
        System.out.println("anwser = " + pyobj.toString());  
    }  
}

输出结果为55

这里有个弊端,即本文要解决的问题简单的py脚本还可,如果引用的第三方,会报错:java
ImportError: No module named xxx

ps这里所说的报错前提是,能成功独立运行引用第三方的py脚本如果直接执行py脚本,都报第三方包找不到,那是你python环境就没设好,不是java调用python的问题。

ps的ps:网上搜ImportError错误,也有一些解决方案,不过按照那些说法,没解决。

下面说第三种方法,也是本文想提供的一种方式。

方式三:

先说一下网上的示例:

Runtime rt = Runtime.getRuntime();  
System.out.println("start");  
Process proc = Runtime.getRuntime().exec("python outfile.py");  
proc.waitFor();  
System.out.println("end");

可以看到这是一种类似于调用控制台执行python脚本的方式,由此给了我一些启发:

利用控制台启动python,执行python脚本,是不是等同于直接运行py脚本呢?

可不可以把一个脚本当做一个方法,利用控制台将参数传递进去?

答案是可以的。示例如下:

java:

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;

public class FirstJava
{
    public static void main(String args[])
    {
          Integer a = 1, b = 2;
          String[] argg = new String[] { "python", currentPath+"/src/main/java/test.py", a, b};
          Process pr = Runtime.getRuntime().exec(argg);

          BufferedReader in = new BufferedReader(new InputStreamReader(pr.getInputStream()));
          String line;
          String result = "";
          while ((line = in.readLine()) != null) {
//                line = decodeUnicode(line);
            result += line;
          }
          in.close();
          pr.waitFor();
    }
}

注:argg参数既可以是String型,形如”python xx/xxx/test.py a b”;也可以是String[]型,形如{“python”,”xx/xxx/test.py”,a,b}。

第一个参数默认python(猜测是程序名称)

第二个参数是py脚本的绝对路径

后面的参数是要传给py脚本的值

对应py脚本:

import sys
import arcpy #第三方包

a = sys.argv[1] #接收第一个参数
b = sys.argv[2] #接收第二个参数

print a+b

这样,python就能接收到java传递的参数,还不会报第三方包异常了。

缺点也是有的:把一个python文件当做一个方法来使用,就没有return了,用print 返回给java,在java中in.readLine()接收。如果py脚本中执行了N次print,java中in.readLine()也会接收N次。

第一次接触python,查了不少资料才勉强解决。如果你有疑问或更好的方法,欢迎留言。


转载自:https://blog.csdn.net/rrrrroy_Ha/article/details/75105732

You may also like...