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

如何在pytest中捕获pybind11封装的C++函数输出的stdout?

问题原因与解决方案

核心原因

capsys 是通过替换Python的sys.stdout/sys.stderr来捕获输出的,但C的std::cout直接操作操作系统的标准输出文件描述符(比如fd=1),完全绕过了Python的IO层,所以capsys无法捕获到这部分输出。而测试报告能看到内容,是因为报告直接收集了终端的所有输出(包括C直接写入的内容)。

解决方法

方法1:改用pybind11的py::print输出

直接在C++代码里用pybind11提供的打印函数,它会将内容输出到Python的sys.stdout,自然能被capsys捕获:

#include <pybind11/pybind11.h>

namespace py = pybind11;

class Ex {
public:
    Ex() {
        py::print("ASSIGNING"); // 替换std::cout
    }
};

PYBIND11_MODULE(your_module, m) {
    py::class_<Ex>(m, "Ex")
        .def(py::init<>());
}

方法2:重定向C++流到Python的IO

pybind11提供了现成的工具来重定向C++的std::cout/std::cerr到Python的输出流,步骤如下:

  1. C++端添加重定向支持:
#include <pybind11/pybind11.h>
#include <pybind11/iostream.h>
#include <iostream>

namespace py = pybind11;

class Ex {
public:
    Ex() {
        std::cout << "ASSIGNING" << std::endl;
    }
};

PYBIND11_MODULE(your_module, m) {
    // 添加流重定向工具
    py::add_ostream_redirect(m, "ostream_redirect");
    py::class_<Ex>(m, "Ex")
        .def(py::init<>());
}
  1. Python测试代码中使用重定向上下文:
def test_ex_capture(capsys):
    from your_module import Ex, ostream_redirect
    
    with ostream_redirect():
        Ex()
    
    captured = capsys.readouterr()
    assert captured.out.strip() == "ASSIGNING"

方法3:手动重定向流缓冲区(进阶)

如果需要更灵活的控制,可以手动将std::cout的缓冲区替换为Python stdout的缓冲区:

#include <pybind11/pybind11.h>
#include <iostream>
#include <Python.h>

namespace py = pybind11;

class Ex {
public:
    Ex() {
        // 临时重定向cout到Python stdout
        auto old_buf = std::cout.rdbuf();
        std::cout.rdbuf(PySys_GetObject("stdout")->ob_type->tp_as_stream->write);
        
        std::cout << "ASSIGNING" << std::endl;
        
        // 恢复原缓冲区
        std::cout.rdbuf(old_buf);
    }
};

PYBIND11_MODULE(your_module, m) {
    py::class_<Ex>(m, "Ex")
        .def(py::init<>());
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 17:23:27