You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Electron+Python后端:如何实现JS与Python的重复数据传递

解决Electron中JS与Python进程间重复传值的问题

看起来你踩了两个常见的坑:一是过早关闭了stdin流导致后续无法写入,二是Python脚本只读取了一次输入就一直循环旧内容。我来帮你一步步解决这个问题:

错误原因分析

你遇到的ERR_STREAM_WRITE_AFTER_END错误,是因为第一次点击按钮时调用了childShellProcess.stdin.end()——这个操作会直接关闭Python进程的标准输入流,之后再尝试往里面写数据自然就会报错。另外,你的Python脚本只在启动时读取了一次输入,之后不管JS传什么新值,它都会一直输出最初的Some Text。

修改后的解决方案

1. JavaScript端代码调整

核心是不要关闭stdin流,并且每次传值时加上换行符(因为Python的readline()是按行读取的):

const {PythonShell} = require('python-shell');

function testSpawn(evt){
  let sendText;
  if (evt.srcElement.id === "btnSpawnProcess"){
    sendText = 'Some Text';
  } else if (evt.srcElement.id === "btnEditProcess"){
    sendText = 'Some Other Text';
  }
  // 写入数据并添加换行,确保Python能正确读取
  childShellProcess.stdin.write(`${sendText}\n`);
}

var options = {mode: 'json'};
var shellProcess = new PythonShell('./model/testSpawn.py', options);
childShellProcess = shellProcess.childProcess;

// 统一监听Python的输出
shellProcess.on('message', function (message) {
  console.log(message);
});

document.addEventListener('DOMContentLoaded', function() {
  document.getElementById("btnSpawnProcess").addEventListener("click", testSpawn);
  document.getElementById("btnEditProcess").addEventListener("click", testSpawn);
});

2. Python端代码调整

需要改成持续监听stdin输入,而不是只读取一次。这里提供两个版本:

版本1:顺序处理(等当前100次输出完再切换新内容)

import sys
import json
import time

# 循环读取stdin的每一行输入
for message in sys.stdin:
    # 去除换行符和空白字符
    message = message.strip()
    if not message:
        continue
    # 输出当前接收到的消息100次
    for _ in range(100):
        print(json.dumps(message, ensure_ascii=False))
        sys.stdout.flush()
        time.sleep(1)

版本2:立即切换(点击按钮后马上输出新内容)

如果想要点击第二个按钮后立即停止输出旧内容,改用新内容,可以用线程实现:

import sys
import json
import time
import threading

current_message = None
is_running = True

def output_thread():
    global current_message
    while is_running:
        if current_message is not None:
            print(json.dumps(current_message, ensure_ascii=False))
            sys.stdout.flush()
            time.sleep(1)

# 启动后台输出线程
threading.Thread(target=output_thread, daemon=True).start()

# 持续读取输入并更新当前消息
for message in sys.stdin:
    message = message.strip()
    if message:
        current_message = message

# 当输入流关闭时停止线程
is_running = False

关键要点总结

  • 不要随意调用stdin.end(),保持输入流打开才能重复传值;
  • JS传值时必须加换行符\n,否则Python无法通过逐行读取获取新内容;
  • Python脚本要持续监听stdin,而不是只读取一次初始输入。

内容的提问来源于stack exchange,提问作者rw_dev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 08:52:54