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

使用python-shell在JS环境中运行Python代码时消息不同步问题

问题:python-shell执行Python代码时消息输出不同步

我用python-shell在JavaScript环境中运行一段会返回多条消息的Python代码,但遇到了消息不同步的问题——第一条消息能在正确时机返回,但后续所有消息会在最后一次性返回,而非逐条输出。

单独运行test.py时消息输出正常,说明问题不在Python代码本身。从每条消息的time:字段能看出,Python代码里各条消息的执行时机是对的,但在浏览器环境中,<2>FIRST TEST会先打印,<3>TEST和<4>MORE TEST要等10秒后才一起打印。

问题截图

我的代码

Python代码(test.py)

import sys
import time
import threading

def test():
    start = time.time()
    end1 = time.time()
    print("<2>FIRST TEST time: {}".format(end1 - start))

    time.sleep(5)
    end2 = time.time()
    print("<3>TEST time: {}".format(end2 - start))

    time.sleep(5)
    end3 = time.time()
    print("<4>MORE TEST time: {}".format(end3 - start))

x = threading.Thread(target=test)
x.start()
sys.stdout.flush()

JavaScript代码(execPyShell.ts)

const exec: () => void = () => {
    console.log('Start')
    let pyshell = new PythonShell('./engine/test.py');
    let newLogs: string[] = [];

    pyshell.on('message', function(message: string) {
        console.log(message);
    })

    pyshell.end(function (err: any) {
        if (err){
            throw err;
        };
        console.log('Finished');
    });
}

解决办法

问题根源是Python的标准输出默认有缓冲机制,子线程中的print输出被缓存,直到线程结束才一次性发送给JavaScript端。可以通过两种方式解决:

方式一:每次print后手动刷新缓冲区

修改Python代码,在每个print语句后调用sys.stdout.flush(),同时主线程等待子线程结束:

import sys
import time
import threading

def test():
    start = time.time()
    end1 = time.time()
    print("<2>FIRST TEST time: {}".format(end1 - start))
    sys.stdout.flush()

    time.sleep(5)
    end2 = time.time()
    print("<3>TEST time: {}".format(end2 - start))
    sys.stdout.flush()

    time.sleep(5)
    end3 = time.time()
    print("<4>MORE TEST time: {}".format(end3 - start))
    sys.stdout.flush()

x = threading.Thread(target=test)
x.start()
x.join()  # 等待子线程执行完毕
sys.stdout.flush()

方式二:禁用Python输出缓冲(更简便)

在python-shell的配置中添加-u参数,让Python以无缓冲模式运行,这样所有print内容会实时输出:

const exec: () => void = () => {
    console.log('Start')
    let pyshell = new PythonShell('./engine/test.py', {
        pythonOptions: ['-u']  // 启用无缓冲输出
    });
    let newLogs: string[] = [];

    pyshell.on('message', function(message: string) {
        console.log(message);
    })

    pyshell.end(function (err: any) {
        if (err){
            throw err;
        };
        console.log('Finished');
    });
}

内容的提问来源于stack exchange,提问作者anti-duhring

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 19:05:35