有没有办法从 Node.js 中调用 Python 脚本并在生成结果后立即显示结果?

Is there a way to call a Python script from within Node.js and show it's results as soon as they are generated?

我想从 Node.js 应用程序(具体来说 Electron.js)中执行 Python 脚本。我想在生成后立即显示输出。 Python 脚本比较大,处理起来比较费时间,但是可以定时输出数据。

我已经用 python-shell and child_process 试过了。但是,当我执行 Python 文件时,仅当程序结束时才显示输出。

我认为这可以使用 shell.on('message',function(){})scriptExecution.stdout.on('data',function()) 来完成,但显然情况并非如此。

这可能吗?我该怎么做?也许使用其他方式...

正如@antont 指出的那样,一旦结果出现在 stdout 上就获得 Python 结果,这很容易使用刷新机制完成。

怎么做

我已经测试了 3 种方法:

  1. 里面Python代码,传一个关键字参数打印:

    print('text', flush=True)
    
  2. 在 Python 代码 中,使用显式刷新:

    import sys
    # Do this every time you want to flush
    sys.stdout.flush()
    
  3. 调用 Python 可执行文件 时,为其提供始终刷新的选项:

    python -u scriptName.py
    

    (请参阅下面两个使用 python-shell and child_process 的示例。

Node.js 例子

使用python-shell

这个例子的关键部分是pythonOptions: ['-u']中的'-u',如果你删除这个选项Python将不会自动刷新(除非你使用上面的方法1或2) .

let PythonShellLibrary = require('python-shell');
let {PythonShell} = PythonShellLibrary;
let shell = new PythonShell('/home/user/showRandomWithSleep.py', {
    // The '-u' tells Python to flush every time
    pythonOptions: ['-u']
});
shell.on('message', function(message){
    window.console.log('message', message);
    window.console.log(new Date())
})

使用child_process

这个例子的关键部分是spawn(pythonExecutable, ['-u', myPythonScript])中的'-u',如果你删除这个选项Python将不会自动刷新(除非你使用上面的方法1或2) .

var myPythonScript = "/home/user/showRandomWithSleep.py";
var pythonExecutable = "python";
var uint8arrayToString = function(data) {
    return String.fromCharCode.apply(null, data);
};
const spawn = require('child_process').spawn;
// The '-u' tells Python to flush every time
const scriptExecution = spawn(pythonExecutable, ['-u', myPythonScript]);
scriptExecution.stdout.on('data', (data) => {
    console.log(uint8arrayToString(data));
    window.console.log(new Date())
});

showRandomWithSleep.py,上面例子中使用的python文件

from random import *
import time
for i in range(5):
    print("showRandomWithSleep.py")
    print(random())
    print(random())
    print(random())
    print(random())
    print(random())
    print(random())
    print(random())
    print(random())
    print(random())
    print(random())
    print(random())
    print(random())
    time.sleep(random()*5)

备注

我测试了上面的例子,结果有点不同。

当使用 python-shell 时,每 print() 行输出打印件。但是,当使用 child_process 时,打印将以块的形式输出。我不知道为什么会这样。

链接