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

Python3无法捕获子进程stdout到变量的问题求助

问题:捕获外部Python脚本输出失败

我出于测试目的,尝试用Python运行另一个Python程序,但无法捕获目标脚本的输出。具体代码如下:

file1.py内容:

print("Hello world")

file1.test.py内容:

import io
import sys
import os
import unittest

EXPECTED_OUTPUT = "Hello world"

class TestHello(unittest.TestCase):
    def test_hello(self):
        sio = io.StringIO()
        sys.stdout = sio
        os.system("python3 path/to/file1.py")
        sys.stdout = sys.__stdout__
        print("captured value:", sio.getvalue())
        self.assertEqual(sio.getvalue(), EXPECTED_OUTPUT)

if __name__ == "__main__":
    unittest.main()

运行测试后,sio.getvalue()返回空值,网上的类似方法无效。我当前用的是Python 3.8.10,也可以切换版本。另外我知道直接导入对象更简单,但现在必须要捕获外部脚本的输出。


解决方案

os.system()会启动独立的子进程,修改当前进程的sys.stdout根本影响不到子进程的输出流。要捕获子进程输出,得用subprocess模块,这是Python官方推荐的子进程管理工具。

修改后的file1.test.py代码:

import subprocess
import unittest

EXPECTED_OUTPUT = "Hello world"

class TestHello(unittest.TestCase):
    def test_hello(self):
        # 调用外部脚本并捕获输出
        result = subprocess.run(
            ["python3", "path/to/file1.py"],
            capture_output=True,
            text=True
        )
        # 取出标准输出并去掉首尾空白(包括默认的换行符)
        captured_output = result.stdout.strip()
        print("captured value:", captured_output)
        self.assertEqual(captured_output, EXPECTED_OUTPUT)

if __name__ == "__main__":
    unittest.main()

关键说明:

  • subprocess.run()是Python 3.5+的标准用法,capture_output=True会同时捕获标准输出和标准错误
  • text=True(Python 3.7+可用,3.7以下用universal_newlines=True)将输出转为字符串,不用手动解码字节流
  • print()默认会在输出末尾加换行符,用strip()可以统一去掉首尾的空白字符,避免因为换行符导致断言失败

这套方案在Python 3.8.10下完全兼容,不需要切换版本。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 11:15:34