Maison > Java > javaDidacticiel > le corps du texte

Comment appeler Python en Java

WBOY
Libérer: 2023-05-17 12:08:12
avant
2285 Les gens l'ont consulté

    Le langage Python regorge de logiciels de gestion de système, de traitement de données et de statistiques, il est donc très nécessaire d'appeler du code Python à partir d'applications Java. commun et pratique. DataX est un outil de synchronisation hors ligne pour sources de données hétérogènes open source par Alibaba. Il est dédié à l'obtention de données stables et efficaces entre diverses sources de données hétérogènes, notamment les bases de données relationnelles (MySQL, Oracle, etc.), HDFS, Hive, ODPS, HBase, FTP. , etc. Fonction de synchronisation. Datax appelle également des scripts Python via Java.

    Java core

    Java fournit deux méthodes, à savoir l'API ProcessBuilder et le moteur de script JSR-223.

    Utilisez ProcessBuilder

    Créez un processus de système d'exploitation local via ProcessBuilder pour démarrer Python et exécuter le script Python. Le script hello.py affiche simplement "Bonjour Python !". L'environnement de développement doit avoir python installé et des variables d'environnement définies.

    @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();
    }
    Copier après la connexion

    Pour réécrire cette phrase, tu peux dire : Commencez à utiliser la commande Python avec un argument, qui est le chemin complet du script Python. Il peut être placé dans le répertoire des ressources du projet Java. Ce qu'il faut noter est : redirectErrorStream(true), afin de fusionner le flux de sortie d'erreur dans le flux de sortie standard lorsqu'une erreur se produit lors de l'exécution du script. Les informations sur les erreurs peuvent être lues en appelant la méthode getInputStream() de l'objet Process. Sans ce paramètre, vous devez utiliser deux méthodes pour obtenir le flux : getInputStream() et getErrorStream(). Après avoir obtenu l'objet Process de ProcessBuilder, vérifiez les résultats en lisant le flux de sortie.

    Utilisation du moteur Java Script

    La spécification JSR-223 a été introduite pour la première fois dans Java 6, qui définit un ensemble d'API de script pouvant fournir des fonctionnalités de script de base. Ces API fournissent des mécanismes de partage de valeurs et d'exécution de scripts entre Java et les langages de script. L'objectif principal de cette spécification est d'unifier l'interaction entre Java et les langages de script dynamiques qui implémentent différentes JVM. Jython est une implémentation Java de Python qui s'exécute sur la JVM. En supposant que nous ayons Jython sur le CLASSPATH, le framework découvre automatiquement que nous avons la possibilité d'utiliser ce moteur de script et nous permet de demander directement le moteur de script Python. Dans Maven, on peut référencer Jython, ou le télécharger et l'installer directement

    <dependency>
        <groupId>org.python</groupId>
        <artifactId>jython</artifactId>
        <version>2.7.2</version>
    </dependency>
    Copier après la connexion

    Vous pouvez lister tous les moteurs de script supportés grâce au code suivant :

    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);
            }
        }
    }
    Copier après la connexion

    Si Jython est dans l'environnement disponible, vous devriez voir la sortie correspondante :

    ...
    Nom du moteur : jython
    Version : 2.7.2
    Langue : python#🎜 🎜#Noms courts :
    python
    jython

    Utilisez maintenant Jython pour appeler le script hello.py :

    @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());
    }
    Copier après la connexion

    Utilisez cette API que ci-dessus L'exemple est plus concis. Lors de la définition de ScriptContext, vous devez inclure un StringWriter afin d'enregistrer la sortie de l'exécution du script. Fournissez ensuite le nom court pour permettre à ScriptEngineManager de trouver le moteur de script, qui peut utiliser Python ou Jython. Enfin, vérifiez que le résultat est conforme aux attentes.

    En fait, vous pouvez également utiliser la classe PythonInterpretor pour appeler directement le code python intégré :

    @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());
        }
    }
    Copier après la connexion

    La méthode exec fournie par la classe PythonInterpreter peut exécuter directement le code Python. Capturez le résultat de l'exécution via un StringWriter comme dans l'exemple précédent. Regardons un autre exemple :

    @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());
        }
    }
    Copier après la connexion

    L'exemple ci-dessus peut utiliser la méthode get pour accéder à la valeur de la variable. L'exemple suivant montre comment détecter les erreurs :

    try (PythonInterpreter pyInterp = new PythonInterpreter()) {
        pyInterp.exec("import syds");
    }
    Copier après la connexion

    L'exécution du code ci-dessus lèvera une exception PyException, ce qui revient à exécuter le script Python localement pour générer une erreur.

    Voici quelques points à noter :

    • PythonIntepreter implémente AutoCloseable et est mieux utilisé avec try-with-resources.

    • Le nom de la classe PythonIntepreter n'est pas un analyseur représentant le code Python exécuté en Jython dans jvm et doit être compilé en bytecode Java avant exécution.

    • Bien que Jython soit une implémentation Python de Java, il peut ne pas contenir tous les mêmes sous-packages que Python natif.

    L'exemple suivant montre comment attribuer des variables Java aux variables Python :

    import org.python.util.PythonInterpreter; 
    import org.python.core.*; 
    class test3{
        public static void main(String a[]){
            int number1 = 10;
            int number2 = 32;
            try (PythonInterpreter pyInterp = new PythonInterpreter()) {
                python.set("number1", new PyInteger(number1));
                python.set("number2", new PyInteger(number2));
                python.exec("number3 = number1+number2");
                PyObject number3 = python.get("number3");
                System.out.println("val : "+number3.toString());
            }
        }
    }
    Copier après la connexion

    Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

    Étiquettes associées:
    source:yisu.com
    Déclaration de ce site Web
    Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
    Tutoriels populaires
    Plus>
    Derniers téléchargements
    Plus>
    effets Web
    Code source du site Web
    Matériel du site Web
    Modèle frontal