Reputation: 2238
In CPython we can get the argument list of a function by following methods. function name is 'aMethod'
import inspect
inspect.getargspec(aMethod)
or
aMethod.func_code.co_varnames
How can I achieve the same thing for a Boost:Python function? I get the following error when I use these methods in for those.
for the first method TypeError: is not a Python function
for the second method AttributeError: 'aMethod' object has no attribute 'func_code'
Upvotes: 1
Views: 1375
Reputation: 1
Careful: This approach will print out all variables in a function, not just its parameters. To wit:
def test4(a, b):
c = a + b
>>> test4.__code__.co_varnames
('a', 'b', 'c')
If you really need just the function parameters, just use the inspect
module:
// given f as callable boost::python::object
auto inspect = python::import("inspect");
auto argspec = inspect.attr("getargspec")(f);
// returns args in argspec[0] (and varargs in [1], keywords in [2], and defaults in [3]).
Upvotes: 0
Reputation: 51881
When accessing a Python attribute on a boost::python::object
, use the attr
member function. For example:
aMethod.func_code.co_varnames
would become
aMethod.attr("func_code").attr("co_varnames")
Here is a complete example.
#include <iostream>
#include <vector>
#include <boost/foreach.hpp>
#include <boost/python.hpp>
#include <boost/python/stl_iterator.hpp>
void print_varnames(boost::python::object fn)
{
namespace python = boost::python;
typedef python::stl_input_iterator<std::string> iterator;
std::vector<std::string> var_names(
iterator(fn.attr("func_code").attr("co_varnames")),
iterator());
BOOST_FOREACH(const std::string& varname, var_names)
std::cout << varname << std::endl;
}
BOOST_PYTHON_MODULE(example)
{
def("print_varnames", &print_varnames);
}
Usage:
>>> def test1(a,b,c): pass
...
>>> def test2(spam, eggs): pass
...
>>> def test3(): pass
...
>>> from example import print_varnames
>>> print_varnames(test1)
a
b
c
>>> print_varnames(test2)
spam
eggs
>>> print_varnames(test3)
>>>
Upvotes: 1