如何在python中对swig矩阵对象进行字符串化

时间:2010-03-30 21:10:51

标签: python swig

我正在使用openbabel的swig包装器(用C ++编写,并通过swig提供python包装器)

下面我只是用它来读取分子结构文件并获取它的unitcell属性。

import pybel
for molecule in pybel.readfile('pdb','./test.pdb'):
    unitcell = molecule.unitcell
    print unitcell
   |..>     
   |..>     
<openbabel.OBUnitCell; proxy of <Swig Object of type 'OpenBabel::OBUnitCell *' at 0x17b390c0> >

unitcell具有CellMatrix()函数,

unitcell.GetCellMatrix()
   <22> <openbabel.matrix3x3; proxy of <Swig Object of type 'OpenBabel::matrix3x3 *' at 0x17b3ecf0> >

OpenBabel :: matrix3x3类似于:

1 2 3
4 5 6
7 8 9

我想知道如何打印出matrix3 * 3的内容。我尝试了__str____repr__

在python中用swing包裹矩阵的内容的任何一般方法?

感谢

2 个答案:

答案 0 :(得分:5)

基于这个openbabel文档,看起来有一个很好的理由,Python绑定没有一个很好的方式来打印matrix3x3 objectmatrix3x3 C ++类重载<<运算符,SWIG将忽略该运算符:

http://openbabel.org/api/2.2.0/classOpenBabel_1_1matrix3x3.shtml

这意味着您需要修改SWIG界面文件(查看http://www.swig.org/Doc1.3/SWIGPlus.html#SWIGPlus_class_extension),将__str__方法添加到C ++中的openbabel::matrix3x3,其中包含<<运营商。您的方法可能看起来很像

std::string __str__() {
  //make sure you include sstream in the SWIG interface file
  std::ostringstream oss(std::ostringstream::out);
  oss << (*this);
  return oss.str();
}

我相信SWIG会在这种情况下正确处理C ++的返回类型std::string,但如果不是,你可能不得不回过头来回复一个字符数组。

此时,您应该能够重新编译绑定,并重新运行Python代码。在str()对象上调用matrix3x3现在应该显示在C ++中使用<<运算符显示的内容。

答案 1 :(得分:0)

除了@jhoon的回答之外,似乎SWIG无法识别 std :: string 返回类型,因此更改函数以返回 const char * 。此外,由于它是类外的函数,因此您不能使用self,但必须使用SWIG的 $ self 变量。

因此,在SWIG .i 文件中,如果您输入以下内容:

%extend OpenBabel::matrix3x3 {
  const char* __str__() {
    std::ostringstream out;
    out << *$self;
    return out.str().c_str();
  }
};

matrix3x3 上调用Python的打印时,你应该得到所需的结果。

如果您发现自己将其添加到许多类中,请考虑将其包装在宏中,如:

%define __STR__()
const char* __str__() {
  std::ostringstream out;
  out << *$self;
  return out.str().c_str();
}
%enddef

然后将其添加到类中:

%extend OpenBabel::matrix3x3 {
  __STR__()
};