2010-03-30 3 views
4

Я использую Swig обертку openbabel (написано на C++, и поставить питон обертку через глоток)Как stringfy глотка объекта матрицы в питоне

Ниже я просто использовать его для чтения структуры молекулы файла и получить свойство ее ячейки.

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__ с ним.

Любой общий способ stringfy содержимого матрицы, завернутой качанием в python?

благодаря

ответ

5

На основании этой документации 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

В дополнение к ответу от @jhoon, кажется, что SWIG не признает станд :: строка тип возвращаемого так изменить функцию, чтобы вернуть константный символ *. Кроме того, поскольку это функция вне класса, вы не можете использовать self, но вы должны использовать переменную $ SWIO.

Так, в SWIG й файл, если вы поместите следующее:

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

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

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

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

, а затем добавить его к классу с:

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

Две проблемы с этим ответом: 1. указанная память высвобождается до того, как вы вернетесь из своей функции, и 2. SWIG поддерживает 'std :: string', но сначала вам нужно выполнить'% include '. – Flexo