כיצד להתקשר לפייתון מג'אווה

1. סקירה כללית

פייתון היא שפת תכנות פופולרית יותר ויותר, במיוחד בקהילה המדעית בשל מגוון העשירים שלה של חבילות מספריות וסטטיסטיות. לכן, זו לא דרישה נדירה להצליח להפעיל קוד Python מיישומי Java שלנו.

במדריך זה, נבחן כמה מהדרכים הנפוצות ביותר להתקשר לקוד פייתון מג'אווה.

2. תסריט פיתון פשוט

במהלך הדרכה זו נשתמש בתסריט פייתון פשוט מאוד אותו נגדיר בקובץ ייעודי בשם שלום.פי:

הדפס ("שלום קוראי באלדונג !!")

בהנחה שיש לנו התקנת פייתון עובדת, כאשר אנו מריצים את הסקריפט שלנו עלינו לראות את ההודעה המודפסת:

$ python hello.py שלום קוראי באלדונג !!

3. ליבת Java

בחלק זה נבחן שתי אפשרויות שונות בהן אנו יכולים להשתמש כדי להפעיל את סקריפט ה- Python שלנו באמצעות Java הליבה.

3.1. באמצעות ProcessBuilder

בואו נסתכל תחילה כיצד אנו יכולים להשתמש ב- ProcessBuilder API ליצירת תהליך מערכת הפעלה מקורי להפעלה פִּיתוֹן ולבצע את התסריט הפשוט שלנו:

@Test ציבורי בטל שניתן PythonScript_whenPythonProcessInvoked_thenSuccess () זורק חריג {ProcessBuilder processBuilder = חדש ProcessBuilder ("python", resolvePythonScriptPath ("hello.py")); processBuilder.redirectErrorStream (נכון); תהליך תהליך = processBuilder.start (); תוצאות רשימה = readProcessOutput (process.getInputStream ()); assertThat ("התוצאות לא צריכות להיות ריקות", תוצאות, זה (לא (ריק ()))); assertThat ("התוצאות צריכות להכיל פלט של הסקריפט:", results, hasItem (containString ("שלום קוראי באלדונג !!")); int exitCode = process.waitFor (); assertEquals ("אין לזהות שגיאות", 0, exitCode); }

בדוגמה ראשונה זו, אנו מריצים את פִּיתוֹן פקודה עם טיעון אחד שהוא הדרך המוחלטת שלנו שלום.פי תַסרִיט. אנחנו יכולים למצוא את זה ב מבחן / משאבים תיקיה.

לסיכום, אנו יוצרים את שלנו ProcessBuilder אובייקט שמעביר את ערכי הפקודה והוויכוח לבנאי. חשוב גם להזכיר את השיחה redirectErrorStream (נכון). במקרה של שגיאות, פלט השגיאות ימוזג עם הפלט הסטנדרטי.

זה שימושי מכיוון שזה אומר שאנחנו יכולים לקרוא כל הודעות שגיאה מהפלט המתאים כאשר אנו קוראים ל- getInputStream () שיטה על תהליך לְהִתְנַגֵד. אם לא מגדירים נכס זה ל- נָכוֹןואז נצטרך לקרוא פלט משני זרמים נפרדים באמצעות ה- getInputStream () וה getErrorStream () שיטות.

כעת, אנו מתחילים את התהליך באמצעות ה- הַתחָלָה() שיטה להשיג א תהליך לְהִתְנַגֵד. ואז אנו קוראים את פלט התהליך ומוודאים שהתוכן הוא מה שאנחנו מצפים לו.

כפי שצוין לעיל, הנחנו שה- פִּיתוֹן הפקודה זמינה דרך נָתִיב מִשְׁתַנֶה.

3.2. עבודה עם מנוע התסריט JSR-223

JSR-223, שהוצג לראשונה ב- Java 6, מגדיר מערך ממשקי API של scripting המספקים פונקציונליות סקריפט בסיסית. שיטות אלה מספקות מנגנונים לביצוע סקריפטים ולשיתוף ערכים בין Java לשפת scripting. המטרה העיקרית של תקן זה הייתה לנסות להביא לאחידות מסוימת ביחסי גומלין עם שפות סקריפט שונות מג'אווה.

אנו יכולים להשתמש בארכיטקטורת מנוע הסקריפט הניתנת לחיבור לכל שפה דינמית בתנאי שיש לה יישום JVM, כמובן. ג'ייתון הוא יישום פלטפורמת Java של Python הפועל ב- JVM.

בהנחה שיש לנו את ג'יתון ב CLASSPATH, על המסגרת לגלות באופן אוטומטי שיש לנו אפשרות להשתמש במנוע סקריפטים זה ולאפשר לנו לבקש את מנוע הסקריפט של פייתון ישירות.

מאחר וג'יתון זמין ממייבן סנטרל, אנחנו יכולים פשוט לכלול אותו ב pom.xml:

 org.python jython 2.7.2 

כמו כן, ניתן גם להוריד ולהתקין ישירות.

בואו לרשום את כל מנועי התסריט העומדים לרשותנו:

ScriptEngineManagerUtils.listEngines ();

אם יש לנו אפשרות להשתמש בג'יתון, עלינו לראות את מנוע התסריט המתאים:

... שם מנוע: jython גרסה: 2.7.2 שפה: python שמות קצרים: python jython 

עכשיו, כשאנחנו יודעים שאנחנו יכולים להשתמש במנוע התסריט של Jython, בואו ונראה איך לקרוא ל שלום.פי תַסרִיט:

@Test ציבורי בטל שניתן PythonScriptEngineIsAvailable_whenScriptInvoked_thenOutputDisplayed () זורק חריג {כותב StringWriter = StringWriter חדש (); הקשר ScriptContext = SimpleScriptContext חדש (); context.setWriter (כותב); מנהל ScriptEngineManager = ScriptEngineManager חדש (); מנוע ScriptEngine = manager.getEngineByName ("פיתון"); engine.eval (FileReader חדש (resolvePythonScriptPath ("hello.py")), הקשר); assertEquals ("צריך להכיל פלט סקריפט:", "שלום קוראי באלדונג !!", writer.toString (). trim ()); }

כפי שאנו רואים, זה די פשוט לעבוד עם ה- API הזה. ראשית, אנו מתחילים בהקמת א ScriptContext המכיל א StringWriter. זה ישמש לאחסון הפלט מהסקריפט שאנו רוצים להפעיל.

לאחר מכן אנו משתמשים ב- getEngineByName שיטת ה- ScriptEngineManager בכיתה להסתכל למעלה וליצור ScriptEngine לשם קצר נתון. במקרה שלנו, אנחנו יכולים לעבור פִּיתוֹן אוֹ ג'ייתון שהם שני השמות הקצרים המשויכים למנוע זה.

כמו קודם, השלב האחרון הוא להביא את הפלט מהתסריט שלנו ולבדוק שהוא תואם למה שציפינו.

4. ג'יתון

בהמשך ל- Jython, יש לנו גם אפשרות להטמיע קוד Python ישירות בקוד ה- Java שלנו. אנו יכולים לעשות זאת באמצעות ה- פיתון מתורגמן מעמד:

@Test הציבור בטל שניתן PythonInterpreter_whenPrintExecuted_thenOutputDisplayed () {try (PythonInterpreter pyInterp = PythonInterpreter חדש ()) {StringWriter output = new StringWriter (); pyInterp.setOut (פלט); pyInterp.exec ("הדפס ('שלום קוראי באלדונג !!')"); assertEquals ("צריך להכיל פלט סקריפט:", "שלום קוראי באלדונג !!", output.toString () .trim ()); }}

משתמש ב פיתון מתורגמן מחלקה מאפשרת לנו לבצע מחרוזת של קוד מקור פייתון באמצעות ה- ביצוע שיטה. כמו קודם אנו משתמשים ב- StringWriter כדי לתפוס את הפלט מביצוע זה.

בואו נראה דוגמה בה אנו מוסיפים שני מספרים יחד:

@ מבחן חלל ציבורי שניתן PythonInterpreter_whenNumbersAdded_thenOutputDisplayed () {try (PythonInterpreter pyInterp = PythonInterpreter חדש ()) {pyInterp.exec ("x = 10 + 10"); PyObject x = pyInterp.get ("x"); assertEquals ("x:", 20, x.asInt ()); }}

בדוגמה זו אנו רואים כיצד אנו יכולים להשתמש ב- לקבל שיטה, כדי לגשת לערך של משתנה.

בדוגמה האחרונה של ג'יתון, נראה מה קורה כששגיאה מתרחשת:

נסה (PythonInterpreter pyInterp = PythonInterpreter חדש ()) {pyInterp.exec ("מערכות ייבוא"); }

כאשר אנו מריצים קוד זה א PyException נזרק ונראה את אותה שגיאה כאילו עבדנו עם פייתון מקורי:

Traceback (השיחה האחרונה האחרונה): קובץ "", שורה 1, ב- ImportError: אין מודול בשם syds

כמה נקודות עלינו לשים לב:

  • כפי ש מתרגם פיתון מכשירים ניתן לסגירה אוטומטית, זה נוהג טוב להשתמש נסה עם משאבים כשעובדים עם הכיתה הזו
  • ה פיתון מתורגמן שם הכיתה אינו מרמז שקוד הפיתון שלנו מתפרש. תוכניות פיתון בג'יתון מנוהלות על ידי JVM ולכן נערכות ל- Java bytecode לפני הביצוע
  • למרות שג'יתון הוא יישום הפייתון עבור Java, ייתכן שהוא לא מכיל את כל אותן חבילות המשנה של פייתון מקורי

5. אפאצ'י קומונס ביצוע

ספריית צד שלישי נוספת שאנו יכולים לשקול להשתמש בה היא Apache Common Exec המנסה להתגבר על חלק מהחסרונות של ממשק ה- API של Java Process.

ה commons-exec חפץ זמין ממייבן סנטרל:

 org.apache.commons commons-exec 1.3 

עכשיו בואו נוכל להשתמש בספריה זו:

@Test הציבור בטל שניתן PythonScript_whenPythonProcessExecuted_thenSuccess () זורק ExecuteException, IOException {String line = "python" + resolvePythonScriptPath ("hello.py"); CommandLine cmdLine = CommandLine.parse (שורה); ByteArrayOutputStream outputStream = ByteArrayOutputStream חדש (); PumpStreamHandler streamHandler = PumpStreamHandler חדש (outputStream); מפעל DefaultExecutor = DefaultExecutor חדש (); executor.setStreamHandler (streamHandler); int exitCode = executor.execute (cmdLine); assertEquals ("אין לזהות שגיאות", 0, exitCode); assertEquals ("צריך להכיל פלט סקריפט:", "שלום קוראי באלדונג !!", outputStream.toString () .trim ()); }

דוגמה זו אינה שונה מדי מהדוגמה הראשונה שלנו ProcessBuilder. אנו יוצרים a CommandLine אובייקט לפקודה הנתונה שלנו. לאחר מכן, הגדרנו מטפל זרמים לשימוש לצילום הפלט מהתהליך לפני ביצוע הפקודה שלנו.

לסיכום, הפילוסופיה העיקרית שעומדת מאחורי ספרייה זו היא להציע חבילת ביצוע תהליכים שמטרתה לתמוך במגוון רחב של מערכות הפעלה באמצעות ממשק API עקבי.

6. שימוש ב- HTTP לצורך יכולת פעולה הדדית

בואו ניקח צעד אחורה לרגע ובמקום לנסות להפעיל את פייתון נשקול ישירות שימוש בפרוטוקול מבוסס כמו HTTP כשכבת הפשטה בין שתי השפות השונות.

למעשה פייתון נשלח עם שרת HTTP מובנה פשוט שבו אנו יכולים להשתמש לשיתוף תוכן או קבצים באמצעות HTTP:

python -m http.server 9000

אם עכשיו נלך אל // localhost: 9000, נראה את התוכן המופיע בספרייה בה השקנו את הפקודה הקודמת.

כמה מסגרות פופולריות אחרות שנוכל לשקול להשתמש בהן ליצירת שירותי אינטרנט או יישומים מבוססי פיתון חזקים יותר הם Flask ו- Django.

ברגע שיש לנו נקודת קצה שאנחנו יכולים לגשת אליה, אנו יכולים להשתמש בכל אחת מכמה ספריות Java HTTP כדי להפעיל את שירות האינטרנט / יישום היישום של Python.

7. מסקנה

במדריך זה למדנו על כמה מהטכנולוגיות הפופולריות ביותר להתקשרות לקוד פייתון מג'אווה.

כמו תמיד, קוד המקור המלא של המאמר זמין באתר GitHub.


$config[zx-auto] not found$config[zx-overlay] not found