2013-06-10 16 views
10

Ho incorporato python in C++ e vorrei sapere se c'è un modo per trovare il tipo di boost :: python :: che è un risultato dopo l'esecuzione di una funzione di un modulo python. Io ho il mio codice come questo:Trova il tipo di oggetto boost python

boost::python::object module_ = boost::python::import("..libName"); 
boost::python::object result_ = module_.attr("..functionName")(arg1, arg2,...); 
//suppose if the result is int, 
int a_ = boost::python::extract<int>(result_); 

Dal frammento di codice di cui sopra, quello che vorrei sapere è se c'è modo di trovare il tipo del risultato prima di estrarlo. Nel codice sopra, il risultato_ potrebbe essere qualsiasi tipo come lista, tuple ...

risposta

3

Ci sono un paio di modi per ottenere il tipo di un oggetto. Quale si utilizza dipende dal formato che si desidera che il risultato sia. È possibile utilizzare result_.attr("__class__") per ottenere la classe come boost :: python :: object. Puoi anche usare lo PyObject_IsInstance function per verificare se è il tipo che pensi sia. Infine, è possibile utilizzare PyObject_Type function per ottenere il tipo di esso come PyObject *.

7

Si può provare questo

std::vector<std::string> list_to_vector(boost::python::list& l) 
{ 
    for (int i = 0; i < len(n); ++i) 
    { 
     boost::python::extract<boost::python::object> objectExtractor(l[i]); 
     boost::python::object o=objectExtractor(); 
     std::string object_classname = boost::python::extract<std::string>(o.attr("__class__").attr("__name__")); 
     std::cout<<"this is an Object: "<<object_classname<<std::endl; 
    } 
    ................................................... 
    ................................................... 
} 

Funziona per me.

2

Dal momento che ti sembra di voler controllare se si tratta di un numero intero, è possibile utilizzare extract<T> x(o):

boost::python::extract<int> n(o); 

if (n.check()) 
    // it's an integer, or at least convertible to one 
else 
    // not an integer 

Il documentation dice:

estratto x (o); costruisce un estrattore la cui funzione membro check() può essere utilizzata per chiedere se una conversione è disponibile senza causare un'eccezione da generare a .

Questo può sembrare come se un galleggiante può essere considerata convertibile a intero, ma provato, e non lo fa. In altre parole, non mi fiderei davvero che faccia la cosa giusta ogni volta!

Per i tipi built-in, in questo caso un intero, penso che sia più sicuro da usare PyInt_Check, ma almeno quando ho testati po 'di codice qui, non era immediatamente disponibile.

In altre parole, se è necessario determinare il tipo di oggetti che non sono built-in Python, seguirei @Aereaux's suggestion di PyObject_IsInstance. (Ma personalmente preferirei avere una base di codice Boost Python pulita, piuttosto che un mix.)

+0

Come hai suggerito non è affidabile. estratto accetterà felicemente numeri interi – Sergei

+1

Sì. Da questo post, ho capito che 'extract' proverà a convertire automaticamente tra tipi compatibili. Il modo per essere sicuri che sia esattamente un numero intero è usare 'PyInt_Check'. – csl