How to stringfy swig matrix object in python

I use swig wrapper openbabel (written in C ++ and supplying a python shell via swig)

Below I just use it to read the molecule structure file and get its unitcell property.

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

A single cell has a CellMatrix () function,

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

OpenBabel :: matrix3x3 looks something like this:

 1 2 3 4 5 6 7 8 9 

I am wondering how to print the contents of a 3 * 3 matrix. I tried __str__ and __repr__ with it.

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

thanks

+4
source share
2 answers

Based on this openbabel documentation, there seems to be a good reason that Python bindings do not come with a good way to print a matrix3x3 object . The C ++ matrix3x3 class overloads the << operator, which SWIG simply ignores:

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

This means that you need to modify the SWIG interface file (see http://www.swig.org/Doc1.3/SWIGPlus.html#SWIGPlus_class_extension ) to add the __str__ method for openbabel::matrix3x3 in C ++ that wraps the statement << . Your method may look very similar to

 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 correctly handles the C ++ return type std::string in this case, but if not, you might have to play around with returning an array of characters.

At this point, you can recompile the bindings and restart your Python code. The str() matrix3x3 to the matrix3x3 object should now display what will be displayed using the << operator in C ++.

+5
source

In addition to the answer from @jhoon, it looks like SWIG does not recognize the return type std :: string, so change the function to return const char *. Also, since this is a function outside the class, you cannot use self, but you must use the SWIG $ 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 invoking Python print on a 3x3 matrix.

If you find that you are adding this to many classes, consider packing in a macro, for example:

 %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__() }; 
0
source

Source: https://habr.com/ru/post/1305607/


All Articles