Heim  >  Artikel  >  Java  >  So rufen Sie Python in Java auf

So rufen Sie Python in Java auf

WBOY
WBOYnach vorne
2023-05-17 12:08:122221Durchsuche

    Die Python-Sprache verfügt über eine Fülle von Softwarepaketen für Systemverwaltung, Datenverarbeitung und Statistik, sodass der Aufruf von Python-Code aus Java-Anwendungen weit verbreitet und praktisch ist. DataX ist ein von Alibaba bereitgestelltes Offline-Synchronisierungstool für heterogene Datenquellen. Es dient der Bereitstellung stabiler und effizienter Daten zwischen verschiedenen heterogenen Datenquellen, einschließlich relationaler Datenbanken (MySQL, Oracle usw.), HDFS, Hive, ODPS, HBase und FTP usw. Synchronisierungsfunktion. Datax ruft auch Python-Skripte über Java auf.

    Java-Kern

    Java bietet zwei Methoden, nämlich ProcessBuilder API und JSR-223 Scripting Engine.

    Verwenden Sie ProcessBuilder

    Erstellen Sie über ProcessBuilder einen lokalen Betriebssystemprozess, um Python zu starten und das Python-Skript auszuführen. Das hello.py-Skript gibt einfach „Hallo Python!“ aus. In der Entwicklungsumgebung muss Python installiert und Umgebungsvariablen festgelegt sein.

    @Test
    public void givenPythonScript_whenPythonProcessInvoked_thenSuccess() throws Exception {
        ProcessBuilder processBuilder = new ProcessBuilder("python", resolvePythonScriptPath("hello.py"));
        processBuilder.redirectErrorStream(true);
        Process process = processBuilder.start();
        List<String> results = readProcessOutput(process.getInputStream());
        assertThat("Results should not be empty", results, is(not(empty())));
        assertThat("Results should contain output of script: ", results, hasItem(containsString("Hello Python!")));
        int exitCode = process.waitFor();
        assertEquals("No errors should be detected", 0, exitCode);
    }
    private List<String> readProcessOutput(InputStream inputStream) throws IOException {
        try (BufferedReader output = new BufferedReader(new InputStreamReader(inputStream))) {
            return output.lines()
                .collect(Collectors.toList());
        }
    }
    private String resolvePythonScriptPath(String filename) {
        File file = new File("src/test/resources/" + filename);
        return file.getAbsolutePath();
    }

    Um diesen Satz umzuschreiben, können Sie sagen: Beginnen Sie mit der Verwendung des Python-Befehls mit einem Argument, dem vollständigen Pfad zum Python-Skript. Es kann im Ressourcenverzeichnis des Java-Projekts abgelegt werden. Was beachtet werden muss, ist:directErrorStream(true), damit der Fehlerausgabestream in den Standardausgabestream zusammengeführt wird, wenn beim Ausführen des Skripts ein Fehler auftritt. Fehlerinformationen können durch Aufrufen der Methode getInputStream() des Process-Objekts gelesen werden. Ohne diese Einstellung müssen Sie zwei Methoden verwenden, um den Stream abzurufen: getInputStream() und getErrorStream(). Nachdem Sie das Process-Objekt von ProcessBuilder erhalten haben, überprüfen Sie die Ergebnisse, indem Sie den Ausgabestream lesen.

    Verwendung einer Java-Skript-Engine

    Die JSR-223-Spezifikation wurde erstmals mit Java 6 eingeführt und definiert eine Reihe von Skript-APIs, die grundlegende Skriptfunktionen bereitstellen können. Diese APIs bieten Mechanismen zum Teilen von Werten und zum Ausführen von Skripts zwischen Java und Skriptsprachen. Der Hauptzweck dieser Spezifikation besteht darin, die Interaktion zwischen Java und dynamischen Skriptsprachen zu vereinheitlichen, die verschiedene JVMs implementieren. Jython ist eine Java-Implementierung von Python, die auf der JVM ausgeführt wird. Vorausgesetzt, wir haben Jython im CLASSPATH, erkennt das Framework automatisch, dass wir die Möglichkeit haben, diese Skript-Engine zu verwenden, und ermöglicht es uns, die Python-Skript-Engine direkt anzufordern. In Maven können wir auf Jython verweisen oder es direkt herunterladen und installieren ...

    Engine-Name: jython

    Version: 2.7.2

    Sprache: Python

    Kurznamen:

    python
    jython



    Nun verwenden Sie Jython, um das hello.py-Skript aufzurufen:

    <dependency>
        <groupId>org.python</groupId>
        <artifactId>jython</artifactId>
        <version>2.7.2</version>
    </dependency>

    Die Verwendung dieser API ist prägnanter als das Beispiel oben. Beim Festlegen des ScriptContext müssen Sie einen StringWriter einschließen, um die Ausgabe der Skriptausführung zu speichern. Geben Sie dann den Kurznamen an, damit ScriptEngineManager die Skript-Engine finden kann, die Python oder Jython verwenden kann. Überprüfen Sie abschließend, ob die Ausgabe den Erwartungen entspricht.

    Tatsächlich können Sie auch die PythonInterpretor-Klasse verwenden, um den eingebetteten Python-Code direkt aufzurufen:

    public static void listEngines() {
        ScriptEngineManager manager = new ScriptEngineManager();
        List<ScriptEngineFactory> engines = manager.getEngineFactories();
        for (ScriptEngineFactory engine : engines) {
            LOGGER.info("Engine name: {}", engine.getEngineName());
            LOGGER.info("Version: {}", engine.getEngineVersion());
            LOGGER.info("Language: {}", engine.getLanguageName());
            LOGGER.info("Short Names:");
            for (String names : engine.getNames()) {
                LOGGER.info(names);
            }
        }
    }
    Die von der PythonInterpreter-Klasse bereitgestellte exec-Methode kann Python-Code direkt ausführen. Erfassen Sie die Ausführungsausgabe über einen StringWriter wie im vorherigen Beispiel. Schauen wir uns ein weiteres Beispiel an:

    @Test
    public void givenPythonScriptEngineIsAvailable_whenScriptInvoked_thenOutputDisplayed() throws Exception {
        StringWriter writer = new StringWriter();
        ScriptContext context = new SimpleScriptContext();
        context.setWriter(writer);
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName("python");
        engine.eval(new FileReader(resolvePythonScriptPath("hello.py")), context);
        assertEquals("Should contain script output: ", "Hello Python!", writer.toString().trim());
    }

    Das obige Beispiel kann die get-Methode verwenden, um auf den Variablenwert zuzugreifen. Das folgende Beispiel zeigt, wie man Fehler abfängt:

    @Test
    public void givenPythonInterpreter_whenPrintExecuted_thenOutputDisplayed() {
        try (PythonInterpreter pyInterp = new PythonInterpreter()) {
            StringWriter output = new StringWriter();
            pyInterp.setOut(output);
            pyInterp.exec("print(&#39;Hello Python!&#39;)");
            assertEquals("Should contain script output: ", "Hello Python!", output.toString().trim());
        }
    }

    Wenn Sie den obigen Code ausführen, wird eine PyException-Ausnahme ausgelöst. Dies entspricht der lokalen Ausführung des Python-Skripts, um einen Fehler auszugeben.

    Ein paar Dinge, die Sie unten beachten sollten:

    PythonIntepreter implementiert AutoCloseable und wird am besten mit Try-with-Ressourcen verwendet.

    Der PythonIntepreter-Klassenname ist kein Parser, der Python-Code darstellt, der in JVM in Jython ausgeführt wird und vor der Ausführung in Java-Bytecode kompiliert werden muss.
    • Obwohl Jython eine Python-Implementierung von Java ist, enthält es möglicherweise nicht alle Unterpakete wie natives Python.
    • Das folgende Beispiel zeigt, wie man Java-Variablen Python-Variablen zuordnet:
    • @Test
      public void givenPythonInterpreter_whenNumbersAdded_thenOutputDisplayed() {
          try (PythonInterpreter pyInterp = new PythonInterpreter()) {
              pyInterp.exec("x = 10+10");
              PyObject x = pyInterp.get("x");
              assertEquals("x: ", 20, x.asInt());
          }
      }

    Das obige ist der detaillierte Inhalt vonSo rufen Sie Python in Java auf. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

    Stellungnahme:
    Dieser Artikel ist reproduziert unter:yisu.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen