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

2 投票
3 回答
3755 浏览
提问于 2025-04-15 16:54

我正在使用 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);
}

附注:在 JRuby、Groovy 和 Rhino 中都能正常工作,也就是说最后一行总是能被返回。

提前谢谢你。

3 个回答

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") 这个代码,似乎可以得到返回的值。

5

这个问题主要是关于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
5

更新:我在最开始的回答中其实没有理解提问者的目标和问题,后来在评论中得到了澄清。所以我会相应地更新我的回答。

首先,按照下面的方式更新 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

撰写回答