在Java中動態傳參調用Python指令碼

來源:互聯網
上載者:User

標籤:lan   複用   java介面   引用   顯示亂碼   cep   ace   b2c   很多   

最近,又接觸到一個奇葩的介面,基於老闆不斷催促趕時間的情況下,在重寫java介面和複用已有的python指令碼的兩條路中選擇了後者,但是其實後者並沒有好很多,因為我是一個對python的認識僅限於其名稱拼字的人,所以,我將把我這一天內從配置環境到最終剛成功呼叫指令碼的過程整理一下,分享給大家。

首先,我先大體上整理一下我的思路(以下以py代替python): 
1. py指令碼如何運行? 
2. java中如何調用py指令碼? 
3. 如何在java中向py指令碼中動態傳參。 
4. 運行發布

接下來,我將順著以上三個方面的思路來分別介紹,並展示我因此踩過的坑。

一、 py指令碼如何運行?
  1. 第一步當然是學習所有的語言都必備的:安裝環境,此處不再贅述,給大家一個我參考的部落格,非常詳細。windows下python環境的安裝 
    包括了安裝環境到簡單的運行語句等內容。
  2. 這樣的話,我在本地已經可以運行出已經寫好的py程式。
  3. 注意:這是我踩的第一個坑,在配置python環境時,要注意你當前啟動並執行py指令碼的版本,因為2.7和3.0兩個版本的相容不是很好,所以環境配置不相同時,可能會導致寫好的py指令碼出現語法錯誤,所以要注意這一點,選擇相應版本的安裝包。
二、java中如何調用py指令碼?
關於java中如何調用py指令碼,網上一搜就有很多種方法,我主要實踐了其中兩種,當然最後採用的一種也是有原因的,下文會詳細解釋。

1. 第一種,Jython 
什麼是jython? 
他其實是一門語言,並非是Java 或者Python的解譯器.用它可以實現,java和python代碼的互相訪問。 
如何使用jython? 
如何使用Jython 
所需jar包: 
為什麼最終沒有選擇使用jython? 
這是我踩過的第二個坑,上面引用的的jython教程,幾個例子都能很好的運行,函數傳參也非常方便,但在運行現有的demo.py時,卻一直在報下面這個錯: 
 
查詢過後,發現是java項目中引包不全的問題,但是基於我對py的瞭解之少,我放棄了這個整合好的方法,畢竟需要一點對py的瞭解。這個等以後有時間再做研究。

2.於是在放棄jython之後,我還是採用了java內建的命令列執行py Runtime.getRuntime().exec(args),然後採用輸出資料流的方式用來擷取參數。 
在封裝好的py指令碼的情況下,如果你不需要傳入參數而只需要執行這個py檔案的話,那麼直接百度就可以擷取得到很多寫好的代碼,我這裡提供一種我這次使用的:

        try {            Process pr = Runtime.getRuntime().exec("python G:\\test.py");            BufferedReader in = new BufferedReader(new InputStreamReader(pr.getInputStream()));            String line;            while ((line = in.readLine()) != null) {                line = decodeUnicode(line);                System.out.println(line);            }            in.close();            pr.waitFor();            System.out.println("end");        } catch (Exception e) {            e.printStackTrace();        }

然後看到這裡,只需要修改Runtime.getRuntime().exec(“”)中的參數改為自己相應的檔案路徑即可,就可以輕鬆結束本次分享,但是,總有但是,我們大多數情況下調用一個複用的部分,都是為了傳入不同的參數以擷取相應的結果,那麼請繼續往下看。

三、如何在java中向py指令碼中動態傳參。
  1. 首先,先來一起明確一個概念,向指令碼中動態傳參,我一開始就很難理解,一個java的參數如何轉為py的參數呢?但是,指令碼就是可以直接用命令列啟動並執行,具體是什麼意思呢?我也不太清楚,但是我在詢問不同人的不同方法之下,找到了一種自己能夠會用並且能夠理解的方法。具體參見:Python獲得命令列傳參
  2. 那麼一言不合上代碼吧: 
    Java代碼:
try {            //需傳入的參數            String a = getPara("car").substring(1), b = "D3455054", c = "LJ12GKS28D4418248", d = "qingdao";            System.out.println("start;;;" + a);            //設定命令列傳入參數            String[] args = new String[] { "python", "/api_test.py", a, b, c, d };            Process pr = Runtime.getRuntime().exec(args);            BufferedReader in = new BufferedReader(new InputStreamReader(pr.getInputStream()));            String line;            while ((line = in.readLine()) != null) {                line = decodeUnicode(line);                System.out.println(line);            }            in.close();            pr.waitFor();            System.out.println("end");        } catch (Exception e) {            e.printStackTrace();        }

py代碼:

import sysprint "指令碼名:", sys.argv[0]for i in range(1, len(sys.argv)):    print "參數", i, sys.argv[i]

運行結果: 

那麼,醬紫就大功告成啦。你只需要根據py指令碼中所需要的參數傳進去就好啦。

運行發布

運行發布有什麼好說的呢? 
這裡也有一點需要注意的,就是伺服器環境的配置,linux一般都是整合好的,其他的我不太清楚,但是最重要的一點,在上線調試時,一定要注意py檔案的路徑存放問題。就醬。

總結

從一開始的完全摸不到頭腦,到現在能夠調用成功,這不到一天的時間,壓力卻是很大的,面對未知的知識,無從下手的感覺我想大家也都經曆過,但在這裡,我十分想感謝那些無私協助我的旁友們~多交流一下,別人不一定有時間能幫你解決,但能夠提供思路的情況下,就能夠早一點找到正確的方向,比如”Python獲得命令列傳參“這個東西,我一開始真是連百度搜尋什麼都不知道,搜到的東西可能跟你需要的完全不搭邊,那麼有一個方向也是好的。當然,這個方向完全正確,奠定了後面動態傳參能夠成功的基礎,哈哈。 
這個部落格只顯示了我的一個特點:我不生產部落格,我只是部落格的搬運工~

附錄:遺留問題

項目中擷取到的中文參數,一向py指令碼中傳參就顯示亂碼,只有中文出現這個情況,到目前也沒有找到解決方案,那麼現在採用了一種曲線救國的方式,但是非常的不好,然而目前並沒有發現更好的解決方案,放在這裡待以後繼續研究,或者大家能有什麼好方法也希望能夠多多交流~

原文地址:61417386

在Java中動態傳參調用Python指令碼

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.