2010-03-30 8 views
4

J'utilise wrapper rasade de openbabel (écrit en C++, et de fournir un emballage de python par rasade)Comment stringfy un objet matrice rasade en python

Ci-dessous je viens de l'utiliser pour lire un fichier de structure moléculaire et obtenir la propriété unitcell de celui-ci.

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

Le unitcell a la fonction CellMatrix(),

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

le OpenBabel :: MATRIX3X3 est quelque chose comme:

1 2 3 
4 5 6 
7 8 9 

Je me demande comment imprimer le contenu du Matrix3 * 3. J'ai essayé __str__ et __repr__ avec elle.

Une manière générale de filtrer le contenu d'une matrice enveloppée par swing en python?

grâce

Répondre

5

Sur la base de cette documentation openbabel, il semble qu'il y ait une bonne raison pour laquelle les liaisons Python ne viennent pas avec une belle façon d'imprimer un matrix3x3 object. La classe matrix3x3 C++ surchargent l'opérateur << qui SWIG simplement ignorer:

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

Cela signifie que vous devrez modifier votre fichier d'interface SWIG (voir http://www.swig.org/Doc1.3/SWIGPlus.html#SWIGPlus_class_extension) pour ajouter une méthode __str__-openbabel::matrix3x3 dans C++ qui enveloppe l'opérateur <<. Votre méthode peut sembler un peu comme

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

Je crois que SWIG gère correctement C++ un type de retour de std::string dans ce cas, mais sinon vous pourriez avoir à jouer avec le retour d'un tableau de caractères. À ce stade, vous devriez pouvoir recompiler les liaisons et réexécuter votre code Python. Appeler str() sur un objet matrix3x3 devrait maintenant afficher ce qui serait affiché avec l'opérateur << en C++.

0

Suite à la réponse de @jhoon, il semble que SWIG ne reconnaît pas le std :: string type de retour donc changer la fonction de retour const char *. En outre, comme il s'agit d'une fonction en dehors de la classe, vous ne pouvez pas utiliser self mais vous devez utiliser la variable $ self de SWIG.

Ainsi, dans le SWIG .i fichier, si vous mettez les éléments suivants:

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

vous devriez obtenir le résultat souhaité lorsque vous appelez l'impression de Python sur un MATRIX3X3.

Si vous vous trouvez en ajoutant ceci à de nombreuses classes, considérez l'enveloppant dans une macro comme:

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

puis l'ajouter à la classe avec:

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

Deux problèmes avec cette réponse: 1. La mémoire pointée sur est libérée avant que vous reveniez de votre fonction et 2. SWIG supporte 'std :: string', mais vous devez d'abord faire'% include '. – Flexo