【问题标题】:what is wrong with c++ streams when using boost.python?使用 boost.python 时 c++ 流有什么问题?
【发布时间】:2010-12-06 01:10:03
【问题描述】:

更新 2:我不知道为什么这仍然被赞成(2014 年 3 月)。自从我多年前问过这个问题以来,这似乎已经解决了。确保您使用的是最新版本的 boost。

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

我在打电话

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

在通过 boost.python 导出到共享库的方法中。它不打印任何东西,但如果我这样做了

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 问题是相关的。

【问题讨论】:

  • 我对 iostreams 和 boost.python 没有问题...也许问题来自更微妙的错误?但是,文档中的技术 (1dl.us/dAD) 对我不起作用,我不得不写 .def("__str__", &amp;print_wrapper&lt;Bernouilli&gt;)self_ns 是什么?另外,在你的方法中,为什么不只是{return os &lt;&lt; b.p() * 100.0 &lt;&lt; "%"; }
  • @rafak 这个问题解释了通过 ostringstream 进行操作的原因:stackoverflow.com/questions/2249018/…
  • @rafak print_wrapper 在哪里定义?我在 boost 中找不到它。
  • 我应该说它是我的:template inline std::string print_wrapper(const C& obj) { std::ostringstream os;操作系统

标签: c++ python boost-python


【解决方案1】:

我不久前也遇到过这个问题,使用 self_ns ,如Build problems when adding `__str__` method to Boost Python C++ classBuild problems when adding `__str__` method to Boost Python C++ class中的答案所述

这里使用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)

【讨论】:

  • 我使用了问题中的self_ns,并没有解决这个问题。
  • 你能试试.def(self_ns::str(self_ns::self))吗?
  • 你也可以尝试在你的 operator
  • 嗨,我确实尝试了该代码。我很确定 Boost.Python 没有正确初始化流的整数到字符串代码。使用 printf 有效,但使用 ostream 无效。
  • @Neil G:你有没有试过我在“只是为了调试”下写的,有用吗?
【解决方案2】:

您是否尝试过改用boost::format?由于您已经在使用boost,所以应该不会太麻烦。

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

另外,尝试将std::endl 显式传递给输出os

【讨论】:

  • 谢谢。该数字仍未显示,但“%”符号在那里。似乎没有创建数字字符串化的缓冲区。
  • 嗯。我会尝试重现问题。
  • 谢谢。如果您无法重现它以及您是否找到了解决方案,请告诉我。
  • 好吧,我写了一个空的Bernoulli类,p定义为double p() {return 2.5;};在 Python 中,str(b) 按预期打印 250%。我使用了 boost 1.42 和 Python 2.5。您使用的是哪个版本?
  • 我现在使用的是 boost 1.48 和 Python 3.1。
【解决方案3】:

您是否尝试过在使用 .str() 方法之前刷新流?

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

【讨论】:

    猜你喜欢
    • 2012-02-26
    • 2011-04-24
    • 2015-01-31
    • 2011-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多