2

我将 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,即总是返回最后一行。

提前致谢。

4

3 回答 3

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
于 2009-12-15T23:38:45.800 回答
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
于 2009-12-11T12:44:26.627 回答
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")看起来你会收回价值。

于 2011-10-04T22:34:36.163 回答