visitor - boost::python::class: programatically obtaining the class name -
i using templated vistors define unified interface several classes. purposes of definint __str__
, __repr__
methods, programatically obtain class name (the "x"
in referenced documentation) boost::python::class
object. possible?
it easy work around passing class name argument visitor's constructor, having automatically more elegant.
boost::python::class_
derives boost::python::object
, possible query __name__
attribute class object.
here simple example:
#include <boost/python.hpp> class x {}; boost_python_module(example) { namespace python = boost::python; python::object x_class = python::class_<x>("x"); // extract class' __name__ attribute, printing whatever passed // class_ constructor. std::cout << boost::python::extract<std::string>(x_class.attr("__name__"))() << std::endl; }
and output:
>>> import example x
to expand upon approach, visitor deriving boost::python::def_visitor
either need to:
- define
__str__
and/or__repr__
function generically returnsboost::python::object
's class' name viao.__class__.__name__
. - extract , store class name, define
__str__
and/or__repr__
function accesses stored value.
the following example demonstrates both of these approaches.
#include <boost/python.hpp> /// @brief helper type used set , boost::python::class_ /// object's type name. template <typename classt> class typed_class_name { public: /// @brief extract , store __name__ /// boost::python::class_ objct. static void set(const classt& c) { name_ = boost::python::extract<std::string>(c.attr("__name__")); } /// @brief return stored name. static std::string get(const typename classt::wrapped_type&) { std::cout << "typed" << std::endl; return name_; } private: static std::string name_; }; template <typename classt> std::string typed_class_name<classt>::name_; /// @brief generically python object's class name. struct generic_class_name { static boost::python::object get(const boost::python::object& self) { std::cout << "generic" << std::endl; return self.attr("__class__").attr("__name__"); } }; class my_def_visitor : public boost::python::def_visitor<my_def_visitor> { friend class boost::python::def_visitor_access; template <class classt> void visit(classt& c) const { // store class name. typed_class_name<classt>::set(c); c .def("__str__", &typed_class_name<classt>::get) // typed .def("__repr__", &generic_class_name::get) // generic ; } }; class x {}; boost_python_module(example) { namespace python = boost::python; python::class_<x>("x") .def(my_def_visitor()) ; }
and usage:
>>> import example >>> x = example.x() >>> str(x) typed 'x' >>> repr(x) generic 'x'
Comments
Post a Comment