使用boost.python时,C++流有什么问题?

15 投票
3 回答
2449 浏览
提问于 2025-04-16 08:05

更新2:我不太明白为什么这个回答还在被点赞(2014年3月)。自从我很多年前问这个问题以来,这个问题似乎已经解决了。确保你使用的是最新版本的boost。

更新:也许C++的流需要初始化才能格式化数字,而在Python加载共享库时这个初始化没有发生?

我在一个通过boost.python导出的共享库的方法中调用了

cout << 1 << "!" << endl; 

但是它什么都不打印。不过如果我这样做

cout << "%" << "!" << endl; 

就可以正常工作。

这很重要,因为我想要这样做:

ostream& operator <<(ostream &os, const Bernoulli& b) {
    ostringstream oss;
    oss << b.p() * 100.0 << "%";
    return os << oss.str();
}

我通过这样做暴露了这个:

BOOST_PYTHON_MODULE(libdistributions)
{
    class_<Bernoulli>("Bernoulli")
        .def(init<>())
        .def(init<double>())

        .def("p", &Bernoulli::p)
        .def("set_p", &Bernoulli::set_p)
        .def("not_p", &Bernoulli::not_p)

        .def("Entropy", &Bernoulli::Entropy)
        .def("KL", &Bernoulli::KL)
        .def(self_ns::str(self))
    ;
}

但是当我在Python中对一个Bernoulli对象调用str方法时,我什么也得不到。我怀疑这个简单的cout问题可能有关联。

3 个回答

0

你有没有在使用 .str() 方法之前先清空一下流呢?

oss << b.p() * 100.0 << "%" << std::flush;
2

你有没有试过用 boost::format 呢?因为你已经在用 boost 了,所以应该不会太麻烦。

boost::format( "%d%%" ) % ( b.p() * 100.0 )

还有一件事,试着把 std::endl 明确地传给输出的 os

3

我之前也遇到过这个问题,使用self_ns的方法就像这里的回答所说的那样,具体可以查看这个链接:在Boost Python C++类中添加`__str__`方法时的构建问题

关于为什么要使用self_ns,Dave在这里有解释:http://mail.python.org/pipermail/cplusplus-sig/2004-February/006496.html


为了调试,请尝试一下

inline std::string toString(const Bernoulli& b) 
{
   std::ostringstream s;
   s << b;
   return s.str(); 
}

然后把.def(self_ns::str(self))替换成

class_<Bernoulli>("Bernoulli")
[...]
.def("__str__", &toString)

撰写回答