Node js 和 python 混合編程之JSON入?yún)⒌膮^(qū)別 如何轉(zhuǎn)換js對象使其能在python腳本中作為python 字典直接使用

Node js 和 python 混合編程的功臣--child_process

眾所周知,當(dāng)node 作為服務(wù)端時,JavaScript也能夠操作本地文件,創(chuàng)建線程,來幫助我們執(zhí)行一些之前在瀏覽器中不能執(zhí)行的動作。但是如果服務(wù)端已經(jīng)有了處理數(shù)據(jù)的python腳本,我們就沒有必要用js實現(xiàn)了,將二者結(jié)合起來,豈不是更方便?所以node js 怎么將python調(diào)用起來,實現(xiàn)node js 和python的混合編程呢?接下來我們將深入研究幾種node js 調(diào)用python的方法以及對應(yīng)的傳參方式。

在node 作為服務(wù)端時,它的child_procee模塊可以起一個進(jìn)程,使其具有了調(diào)用其他語言程序的功能。究其原因,是child_process 模塊提供了衍生子進(jìn)程的功能,子進(jìn)程與Node.js 的父進(jìn)程之間建立了 stdin、stdout 和 stderr 的管道,使數(shù)據(jù)能夠以非阻塞的方式在管道中流通,從而實現(xiàn)了兩個不同語言程序之間的通信。

node js調(diào)用python的兩種常用方法是exec 和spawn。其對應(yīng)的入?yún)⑿问揭灿袇^(qū)別。詳細(xì)功能以及child_process模塊的其他功能可以參考其官網(wǎng)child_process官網(wǎng)鏈接。我們這里只把它們的區(qū)別寫出來。

示例

先把兩個例子寫出來,然后再比較他們之間的區(qū)別和原理。

假設(shè)我們要執(zhí)行的python腳本名稱叫做textPython.py,建它放在python文件夾下面,然后我們在python同級目錄下面創(chuàng)建一個js腳本,命名為exampleNodeCallPython.js。

首先要引入創(chuàng)建子進(jìn)程的模塊child_process,同時還需要一個path模塊,利用它來獲取python腳本的路徑。如下:
const cp = require("child_process");

const path = requier("path");

const scriptFileName = path.join(__dirname,"python",' textPython.py');

scriptFileName就是我們要執(zhí)行的python腳本路徑名稱。試著在命令行中直接執(zhí)行scriptFileName 代表的字符串,發(fā)現(xiàn)python 腳本被調(diào)用了起來。

接下來用node js來運(yùn)行它,在windows上,可以用下面兩種方法執(zhí)行。

方法1:利用child_process的spawn啟一個cmd 進(jìn)程,向它傳入要執(zhí)行的命令。其中inputPara 是node js向python腳本傳入的參數(shù)。

代碼如下:

const pyPid = cp.spawn("cmd.exe",['/c',"python",scriptFileName,inputPara]);

pyPid.stdout.on('data',(data)=>{

? ? console.log(data);

});

pyPid.stderr.on('data',(data)=>{

? ? console.log(data);

});

pyPid.on('exit',(data)=>{

? ? console.log(data);

});

方法2:使用child_process的exec,向其傳入要運(yùn)行的命令。

cp.exec("python" + "? " + scriptFileName + "? " + inputPara, function(err,data){

? ? console.log(data);

});

child_process.exec和child_process.spawn的區(qū)別

接下來我們來看一下這兩個的區(qū)別,首先從node官方解釋看,exec是在spawn基礎(chǔ)上實現(xiàn)的,調(diào)用exec,node會衍生一個 shell 并在 shell 上運(yùn)行命令,然后當(dāng)執(zhí)行完成時會將stdout 和 stderr 傳入到到回調(diào)函數(shù)。其中shell在 Windows 上默認(rèn)為 process.env.ComSpec。而對于spawn 我們可以設(shè)置它的shell選項為cmd.exe 然后將要執(zhí)行的命令傳入進(jìn)去。

因此,在windows上,他們第一個區(qū)別是exec可以不用傳入shell ,它使用默認(rèn)的。而spawn指定shell,在windows上,我們可以傳入cmd.exe。

第二個區(qū)別:exec 運(yùn)行python腳本的標(biāo)準(zhǔn)輸出,要等到整個python腳本運(yùn)行完成后,才會返回給回掉函數(shù)。而spawn運(yùn)行時,可以對其生成的進(jìn)程的stdout進(jìn)行監(jiān)聽,這樣可以實時的查看python腳本的標(biāo)準(zhǔn)輸出。不用等到python腳本執(zhí)行完畢才能查看運(yùn)行結(jié)果。

第三個區(qū)別:最后的也是最重要的一個,當(dāng)我們通過node js 調(diào)用python時,總要給它傳入一些參數(shù),好讓python 根據(jù)不同入?yún)磉\(yùn)行。如果我們向python腳本傳入的參數(shù)是JSON字符串時,exec和spawn就有一個重要的區(qū)別。

JSON字符串通過spawn方法傳入python腳本后,在python腳本中通過json.loads方法可將其轉(zhuǎn)換為python中的字典對象,能夠直接使用。但是當(dāng)通過exec 傳入python腳本時,傳入后會刪除字符串中的引號,無法通過json.loads將其轉(zhuǎn)換為python中的字典對象。在通過exec傳入時,需要利用正則表達(dá)式,對引號加上轉(zhuǎn)義,保留JSON字符串中的引號,這樣才可以在python腳本中通過json.loads將其轉(zhuǎn)換為字典對象來使用。

在node js中利用正則表達(dá)式對json字符串中的引號進(jìn)行轉(zhuǎn)義。

jsonobj.replace(/\"/g,"\\\"");

Node js中的數(shù)據(jù)對象在python腳本中仍作為數(shù)據(jù)對象

在js中,我們可以通過JSON.stringify()將JS對象轉(zhuǎn)換為JSON,然后將JSON按照上面說的方法傳入到python腳本中,在python中調(diào)用json.loads將JSON轉(zhuǎn)換為python中的數(shù)據(jù)對象,然后可以直接使用。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容