javascript - 第一个结束后如何在 Node.js 中生成一个新的 Python 子进程?
问题描述
我在我的 node.js 应用程序中使用 Python 脚本的输出。
但是,我需要再查询一次(并且可能多次)。
我不能这样做,因为 Python 进程结束并且无法重新启动。我试图重新分配变量,但它不起作用。如何再次启动 Python 脚本?这是我的代码:
var spawn = require('child_process').spawn,
interval_data = [1,2,4,5,6,7],
interval_dataString = '';
var py = undefined
startPython()
py.stdout.on('data', function(data){
interval_dataString += data.toString();
console.log(interval_dataString)
});
py.stdout.on('end', function(){
console.log('Alpha Component =',interval_dataString);
setTimeout(() => {
startPython()
},1000)
});
function startPython() {
py = undefined
py = spawn('python', ['dfa.py'])
py.stdin.write(JSON.stringify(interval_data));
py.stdin.end();
}
这是Python代码:
## compute_input.py
import sys, json, numpy as np
#Read data from stdin
def read_in():
lines = sys.stdin.readlines()
#Since our input would only be having one line, parse our JSON data from that
return json.loads(lines[0])
#lines = "[1,2]" # for testing
#return json.loads(lines) # for testing
def main():
#get our data as an array from read_in()
lines = read_in()
#create a numpy array
np_lines = np.array(lines)
#use numpys sum method to find sum of all elements in the array
lines_sum = np.sum(np_lines)
#return the sum to the output stream
print(lines_sum)
#start process
if __name__ == '__main__':
main()
解决方案
您覆盖子进程。所以你不能再使用原来的对象(事件发射器)。
它可能比你更简单:)
只需在“start”函数中调用/移动事件发射器。因此,每次生成子对象时,都会使用新的子对象/事件发射器。
const { spawn } = require("child_process");
const interval_data = [1, 2, 4, 5, 6, 7]
const interval_response = [];
// use this as exit strategie
var should_restart = true;
function start() {
// spawn python child
let child = spawn("python3", ["dfa.py"]);
// would be better to work on buffer objects
// create on final child/python exit a string out of the buffer
child.stdout.on("data", (data) => {
interval_response.push(data.toString());
});
// listen for the close event
child.on("close", () => {
if (should_restart) {
// feedback
console.log("Alpha Component =", interval_response.join());
setTimeout(() => {
start();
}, 1000)
} else {
// nope, not now!
console.log("DIE!", interval_response);
// Do what ever you want with the result here
}
});
// write stuff to python child process
child.stdin.write(JSON.stringify(interval_data));
}
start();
// let the programm run for min. 5sec
setTimeout(() => {
should_restart = false;
}, 5000);
用你的 python 代码测试。
node index.js
Alpha Component = 3
Alpha Component = 3
,3
Alpha Component = 3
,3
,3
Alpha Component = 3
,3
,3
,3
DIE! [ '3\n', '3\n', '3\n', '3\n', '3\n' ]
我以为你实际上是从标准输入读入你的 python 脚本。(而且不仅是一个虚拟函数)
但是对于节点部分,它不应该有任何差异。
在 Ubuntu 18.04 x64 上测试,节点:v13.14.0,python:3.6.9。
编辑:
根据您的 python 片段创建,该脚本从标准输入读取并创建所有传递的数字的总和:
import sys, json
def main():
data = sys.stdin.read()
data = json.loads(data)
#print("debug:", data)
chunks_sum = sum(data)
#print("debug", chunks_sum)
sys.stdout.write(str(chunks_sum))
#start process
if __name__ == '__main__':
main()
修改启动功能:
function start() {
// spawn python child
let child = spawn("python3", ["dfa.py"]);
// would be better to work on buffer objects
// create on final child/python exit a string out of the buffer
child.stdout.on("data", (data) => {
// since your python code just create
// a sum of all numbers, store the
// returend stuff as number
interval_response.push(Number(data));
});
// listen for the close event
child.on("close", () => {
if (should_restart) {
// feedback
console.log("Alpha Component =", interval_response);
setTimeout(() => {
start();
}, 1000)
} else {
// nope, not now!
console.log("DIE!", interval_response);
// create sum of all sum chunks from python
// not sure what you want to do with the "interval_response" array
// just for demo purpose
let sum = interval_response.reduce((pv, cv) => pv + cv, 0);
console.log("Total sum", sum);
}
});
// write stuff to python child process
//child.stdin.write();
child.stdin.end(JSON.stringify(interval_data));
}
改为child.stdin.write
,child.stdin.end
python 现在也可以“启动”,dosnt 必须等待更多数据。
注意:我不知道 IPC/stdio“缓冲”是如何工作的。如果你处理大数据,也许你会过期一些可疑的东西。
此外,我们将写入“stdout”的python数据存储为数组中的数字interval_response
,因为您只需计算我们写入“stdin”的数据的总和。
推荐阅读
- vuejs2 - 在带有复选框的项目列表中,仅选中 1 个项目
- omnet++ - 如何为每条消息发送一个“结构”向量?
- python - 在 1D NumPy 数组中查找值的索引/位置(具有相同的值)
- json - 如何在 kotlin 中编辑嵌套的 JSON
- python - 在 python 函数中运行 webdriver 的问题
- angular - 如何在angular7中的单个formControl中添加多种输入类型?
- regex - 使用正则表达式从字符串中删除数据
- javascript - 如何从firebase角度查询嵌套的孩子?
- android - 在 andoride 中使用 python 和 kivy
- javascript - 平面 JSON 展开为具有多个父级的层次结构作为字符串