有没有办法从 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 种方法:
里面Python代码,传一个关键字参数打印:
print('text', flush=True)
在 Python 代码 中,使用显式刷新:
import sys
# Do this every time you want to flush
sys.stdout.flush()
调用 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 时,打印将以块的形式输出。我不知道为什么会这样。
链接
我想从 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 种方法:
里面Python代码,传一个关键字参数打印:
print('text', flush=True)
在 Python 代码 中,使用显式刷新:
import sys # Do this every time you want to flush sys.stdout.flush()
调用 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 时,打印将以块的形式输出。我不知道为什么会这样。