gpt4 book ai didi

javascript - Node.js:是否可以为 python 交互式 shell (REPL) 制作适配器?

转载 作者:行者123 更新时间:2023-12-01 17:17:44 27 4
gpt4 key购买 nike

可以使用readline在 Node.js 中读取一行 python 代码,然后将其发送到 python 交互式 shell spawn ed 作为子进程,然后接收输出?

我知道这是可能的:

import { spawn } from "child_process";

const py = spawn("python", ["-i"]);

py.stdout.on("data", (data) => {
console.log(`stdout: ${data}`);
});

py.stdin.write('print("hello from python!")\n');

// will get 'stdout: hello from python!'

但是,这不起作用:

import { spawn } from "child_process";
import * as readline from "readline";

const py = spawn("python", ["-i"]);

py.stdout.on("data", (data) => {
console.log(`stdout: ${data}`);
});

py.stdin.write('print("hello from python!")\n');

const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
rl.prompt();
rl.on("line", (line) => {
py.stdin.write(line);
rl.prompt();
}).on("close", () => {
process.exit()
});

我想这样做是因为我想在 Node.js 中为 python 开发一个接口(interface)。通过 spawn 执行独立的 python 命令/文件很简单,但我想构建一个功能齐全的界面,它具有与 Reticulate 类似的功能在 R。

最佳答案

我有一个类似的应用程序,我设法让它运行得足以满足我的需要:a processToPromise function .
缺点是它总是必须在每个 call 上注册新的事件监听器。 .基本上,它等待交互式 Python shell 打印它的 >>>在您的命令完成并为您提供同时出现的输出之后。

此外,您不能多次异步调用此函数而不会得到困惑的结果。
首先尝试一些简单的打印语句,看看你得到了你所期望的。

一些代码供引用:

const child_process = require('child_process');

class InteractiveProcessHandle {
private process: any;

public outputLog: string;
public latestOutput: string;

private processToPromise(process: any) {
return new Promise<string>((resolve, reject) => {
console.log("+++ creating promise");
process.stdout.removeAllListeners();
process.stderr.removeAllListeners();
process.stdin.removeAllListeners();

let lastString: string = '';

process.stdout.on("data", (data: any) => {
data = data.toString().trim();
this.update(data);
if (data.endsWith('>>>')) {
resolve(lastString);
}
lastString = data;
});
process.stderr.on("data", (data: any) => {
data = data.toString().trim();
this.update(data);
if (data.endsWith('>>>')) {
resolve(lastString);
}
lastString = data;
});
process.stdin.on("error", () => {
console.log("Failure in stdin! ... error");
reject();
});
process.stdin.on("close", () => {
console.log("Failure in stdin! ... close");
reject();
});
process.stdin.on("end", () => {
console.log("Failure in stdin! ... end");
reject();
});
process.stdin.on("disconnect", () => {
console.log("Failure in stdin! ... disconnect");
reject();
});
process.stdout.on("error", () => {
console.log("Failure in stdout! ... error");
reject();
});
process.stdout.on("close", () => {
console.log("Failure in stdout! ... close");
reject();
});
process.stdout.on("end", () => {
console.log("Failure in stdout! ... end");
reject();
});
process.stderr.on("error", () => {
console.log("Failure in stderr! ... error");
reject();
});
process.stderr.on("close", () => {
console.log("Failure in stderr! ... close");
reject();
});
process.stderr.on("end", () => {
console.log("Failure in stderr! ... end");
reject();
});
console.log("+++ done creating promise");
});
}

private update(data: any) {
this.latestOutput = data;
this.outputLog += data + "\n";
console.log(`logging from update: "${data}"`);
}

public call(command: string): Promise<string> {
console.log(`called: "${command.trim()}"`);
let promise = this.processToPromise(this.process);
this.process.stdin.write(command);
return promise;
}

constructor(call: any, options: any) {
this.latestOutput = "";
this.outputLog = "";

this.process = child_process.spawn(call, options, { shell: true });
this.process.stdout.setEncoding('utf8');
this.process.stderr.setEncoding('utf8');
}
};

var interactive_python = new InteractiveProcessHandle('python', ['-i']);

async () => {
await interactive_python .call('');
await interactive_python .call('x = 20');
let x = await clang_build.call('print(x)\n');
console.log('x = ', x);
}

关于javascript - Node.js:是否可以为 python 交互式 shell (REPL) 制作适配器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61115778/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com