【问题标题】:Integrate python scripts within Java在 Java 中集成 python 脚本
【发布时间】:2019-03-14 15:54:30
【问题描述】:

所以,我真的不知道如何正确表述这一点,但我会尽力而为。

我正在编写一个游戏引擎(实际上并不是为了任何事情,我正在尝试很多方法来让某些事情通过编程方式来练习)。为此,我想要编写脚本。我知道如何在 Java 中添加脚本,但我见过使用多种语言的游戏引擎。

所以我想要的是添加与 Java 进程一起运行并且可以与 Java 对象交互的 python 脚本。

像这个有一些参数的Java对象(只是一个例子)

public class Entity {

    Script script = new Script ( "example.py" );

    loc_x = 0;
    loc_y = 0;
    loc_z = 0;

    public void update () {
        script.run ();
    }
}

python 脚本是这样的

loc_x += 1
loc_z = loc_x

entity.loc_x += 1
entity.loc_z = entity.loc_x

我只是无法实现这一点。如果这个问题已经被问过,请告诉我。 If Runtime.getRuntime ().exec ( "example.py" ); 是我最好的选择,这很好。在那种情况下,我只想知道如何共享这些参数。

另外,如果另一种语言(例如;LUA)更适合这样的事情,那也没关系。我对这个问题完全空白。

【问题讨论】:

  • 更常见的做法是将 Python 集成到用 C 或其他可以自然与 C API 交互的语言编写的程序中。使用 Java,嵌入 Python 的选项更加笨拙或过时(如 Jython)。
  • 那么你会推荐我使用 Python 以外的其他语言,还是从 Java 切换 () 到 C# 之类的其他语言?
  • 我不知道现在人们想要在 Java 程序中编写脚本时会做什么。也许他们只是写更多的Java。也许他们使用 Scala 或其他一些 JVM 语言。也许他们使用 Jython。也许他们将 CPython 嵌入了 JNI 或 JNA 之类的东西。有很多选择,我没有尝试过其中的大部分。
  • Scala 对我来说是一门新语言。我查找了它并与 java 进行了惊人的集成,但它并没有真正让我像 python 那样兴奋......经过进一步的搜索,我发现了一些非常简单和好的东西。有时大声说出一些事情或(在互联网上)发布问题似乎会使一个人的大脑开始行动有所不同。我会尽快发布我自己的答案,以防其他人在项目中需要这个。

标签: java python embed


【解决方案1】:

所以实际上这很简单,Java 内置了这个功能。

Java 有一个叫做“ScriptEngineManager”的东西。要使用它,您只需执行以下操作:

ScriptEngineManager sem = new ScriptEngineManager ();
ScriptEngine se = sem.getEngineByName ( "python" );

现在有几种方法可以运行脚本。简单地调用se.eval () 方法。您可以给它一个 String 或一个 Reader,这样它就会运行脚本。

现在要让它有一些变量,只需使用se.put 方法。你需要给这两个参数;一个字符串和一个对象。

例如:

se.put ( "entity", entity ); // with entity being defined earlier

唯一要记住的是这个脚本管理器没有内置的 python 支持。您需要为此创建自己的 ScriptEngine 或使用第三方软件。我找到了jython,这似乎工作得很好。如果您下载独立的 jar 并将其放在您的类路径中,它就可以工作。不需要任何函数调用。

现在,您可以在脚本中调用实体的任何公共成员。所有对象、值和那些子对象都会传递给脚本。

我的结束代码:

实体类

public class Entity {

    String source =
            "entity.loc_x += 1\n" +
            "entity.loc_z = entity.loc_x";
    ScriptEngine se;

    loc_x = 0;
    loc_y = 0;
    loc_z = 0;

    public Entity () {
        ScriptEngineManager sem = new ScriptEngineManager ();
        se = sem.getEngineByName ( "python" );
        se.put ( "entity", this );
    }

    public void update () {
        se.eval ( source );
    }
}

我希望我能帮助任何人。修补所有这些非常有趣。

【讨论】:

    猜你喜欢
    • 2013-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-12
    • 1970-01-01
    • 1970-01-01
    • 2010-11-10
    相关资源
    最近更新 更多