使用JSR-223从Jython脚本中获取数据

时间:2009-12-11 10:59:40

标签: java python jython jsr223

我正在使用Jython 2.5.1和JSR-223(即javax.script包),我希望返回Python脚本的最后一行。例如,在评估此脚本后:

class Multiplier:

  def multiply(self, x, y):
    return x * y

Multiplier().multiply(5, 7)

我应该回到35岁,但我得到了null。另一方面,它适用于其他测试:

5 * 7

我做错了什么?

这是Java代码:

public static void main(String[] args) throws Exception {
    ScriptEngine engine = new ScriptEngineManager().getEngineByName("python");

    FileReader f = new FileReader("Multiplier.py");
    Object result = engine.eval(f);
    //assert(result == 35);
}

PS:它适用于JRuby,Groovy和Rhino,即最后一行总是返回。

提前致谢。

3 个答案:

答案 0 :(得分:4)

这是一个Python语言问题,而不是Jython或JSR 223问题。 Python区分表达式(具有值)和语句(不具有)。您传递的脚本是一个声明。如果你传递了一个表达式,它就有一个值。

您看到与Ruby和JavaScript不同的原因是复合语句具有评估的最后一个语句的值。例如,比较Ruby:

>> (2 ; 3) + 5
=> 8
>> (x = 5) + 7
=> 12

使用Python:

>>> (2 ; 3) + 5
  File "<stdin>", line 1
    (2 ; 3) + 5
       ^
SyntaxError: invalid syntax
>>> (x = 5) + 7
  File "<stdin>", line 1
    (x = 5) + 7
       ^
SyntaxError: invalid syntax

JavaScript似乎介于两者之间。与Ruby一样,赋值也会评估为赋值。但是,返回块中的最后一个计算语句但不能用作表达式的一部分:

> { 2 ; 3 }
3
> { 2 ; 3 } + 5
5
> (x = 5) + 7
12

答案 1 :(得分:3)

更新:我实际上错过了我在评论中澄清的初步答案中OP的目标(和问题)。我正在更新我的答案。

首先更新Multiplier.py脚本,如下所示:

class Multiplier:

  def multiply(self, x, y):
    return x * y

x = Multiplier().multiply(5, 7)

然后从Java代码中调用它:

public static void main(String[] args) throws Exception {
    ScriptEngine engine = new ScriptEngineManager().getEngineByName("python");

    FileReader f = new FileReader("Multiplier.py");
    engine.eval(f);
    Object x = engine.get("x");
    System.out.println("x: " + x);
}

运行上面的代码时,我得到以下输出:

x: 35

答案 2 :(得分:2)

我遇到了同样的问题。我编写了一个支持JSR223的脚本库,并提交了http://bugs.jython.org/issue1798

$ python
Python 2.6.6 (r266:84292, Sep 15 2010, 16:22:56) 
[GCC 4.4.5] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> x=5<br/>
>>> x<br/>
5
>>>

至少如果你eval("x=5\nx"),你似乎会得到价值。