如何在 python 中 stringfy 一个 swig 矩阵对象

发布于 2024-08-27 03:41:27 字数 872 浏览 11 评论 0原文

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

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

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> >

单元格具有函数 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 包装的矩阵的内容进行字符串化吗?

谢谢

I am using swig wrapper of openbabel (written in C++, and supply a python wrapper through swig)

Below i just use it to read a molecule structure file and get the unitcell property of it.

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> >

The unitcell has function CellMatrix(),

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

the OpenBabel::matrix3x3 is something like :

1 2 3
4 5 6
7 8 9

i am wondering how to print out the contents of the matrix3*3 . I have tried __str__ and __repr__ with it.

Any general way to stringfy the contents of a matrix wrapped by swing in python ?

thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

故人如初 2024-09-03 03:41:27

根据这个 openbabel 文档,看起来 Python 绑定没有提供打印 matrix3x3 对象 的好方法是有充分理由的。 matrix3x3 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) 在 C++ 中向 openbabel::matrix3x3 添加一个 __str__ 方法,该方法包装了 << 运算符。您的方法可能看起来很像

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 代码。现在,在 matrix3x3 对象上调用 str() 应该显示 C++ 中使用 << 运算符显示的内容。

Based on this openbabel documentation, it looks like there is a good reason the Python bindings don't come with a nice way to print a matrix3x3 object. The matrix3x3 C++ class overloads the << operator, which SWIG will simply ignore:

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

This means that you'll need to modify your SWIG interface file (look at http://www.swig.org/Doc1.3/SWIGPlus.html#SWIGPlus_class_extension) to add a __str__ method to openbabel::matrix3x3 in C++ which wraps the << operator. Your method might look a lot like

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

I believe that SWIG will properly handle C++ a return type of std::string in this case, but if not you might have to play around with returning a character array.

At this point, you should be able to recompile the bindings, and rerun your Python code. Calling str() on a matrix3x3 object should now display what would be displayed with the << operator in C++.

败给现实 2024-09-03 03:41:27

除了@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 的 print 时,您应该会得到所需的结果。

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

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

然后使用以下命令将其添加到类中:

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

Further to the answer from @jhoon, it seems that SWIG doesn't recognise the std::string return type so change the function to return const char*. Also, since it is a function outside the class, you can't use self but you must use SWIG's $self variable.

So, in the SWIG .i file, if you put the following:

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

you should get the desired result when calling Python's print on a matrix3x3.

If you find yourself adding this to many classes, consider wrapping it in a macro like:

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

and then adding it to the class with:

%extend OpenBabel::matrix3x3 {
  __STR__()
};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文