Как создать объект матрицы Swig в Python - PullRequest
4 голосов
/ 31 марта 2010

Я использую оболочку Swig openbabel (написана на C ++ и поставляю оболочку Python через Swig)

Ниже я просто использую его, чтобы прочитать файл структуры молекулы и получить его свойство 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> >

Единица ячейки имеет функцию 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

Мне интересно, как распечатать содержимое матрицы3 * 3. Я попробовал __str__ и __repr__ с ним.

Есть ли какой-нибудь общий способ для строкового преобразования содержимого матрицы, обернутой swing в python?

спасибо

Ответы [ 2 ]

5 голосов
/ 31 марта 2010

Исходя из этой документации openbabel, похоже, что есть веская причина, по которой привязки Python не предоставляют хороший способ печати matrix3x3 object. Класс 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), чтобы добавить __str__ метод к openbabel::matrix3x3 в C ++, который заключает в себе оператор <<. Ваш метод может выглядеть очень похоже на

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

0 голосов
/ 21 июня 2012

В дополнение к ответу @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();
  }
};

вы должны получить желаемый результат при вызове печати Python для matrix3x3 .

Если вы обнаружите, что добавляете это во многие классы, рассмотрите возможность обернуть его в макрос, например:

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

и добавление его в класс с помощью:

%extend OpenBabel::matrix3x3 {
  __STR__()
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...