Reputation: 141
I have been embedding python into c++ and I would like to know if there is a way to find the type of the boost::python::object which is a result after executing a function of a python module. I have my code like this:
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_);
From the above code snippet, what i would like to know is if there is way to find the type of the result before extracting it. In the above code, the result_ might be any type like list, tuple...
Upvotes: 14
Views: 8289
Reputation: 11358
Since you seem to want to check if it's an integer, you can use 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
The documentation says:
extract x(o); constructs an extractor whose check() member function can be used to ask whether a conversion is available without causing an exception to be thrown.
This may sound as if a float may be deemed convertible to integer, but I tried it, and it doesn't. In other words, I wouldn't really trust that it does the right thing every time!
For built-in types, in this case an integer, I think it's more safe to use PyInt_Check
, but at least when I tested some code here, it wasn't immediately available.
In other words, if you need to determine the type of objects that are not Python built-ins, I'd follow @Aereaux's suggestion of using PyObject_IsInstance
. (But I'd personally like better to have a clean Boost Python code base, rather than a mix.)
Upvotes: 5
Reputation:
You can try this
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;
}
...................................................
...................................................
}
It works for me.
Upvotes: 13
Reputation: 855
There are a couple ways to get the type of an object. Which one you use depends on what format you want the result to be. You could use result_.attr("__class__")
to get the class as a boost::python::object. You could also use the PyObject_IsInstance function to check if it is the type you think it is. Last, you could use the PyObject_Type function to get the type of it as a PyObject*.
Upvotes: 4