boost::python::class_
派生自boost::python::object
,因此可以__name__
从类对象中查询属性。
这是一个简单的例子:
#include <boost/python.hpp>
class X {};
BOOST_PYTHON_MODULE(example)
{
namespace python = boost::python;
python::object x_class = python::class_<X>("X");
// Extract the class' __name__ attribute, printing whatever was passed to
// class_ constructor.
std::cout << boost::python::extract<std::string>(x_class.attr("__name__"))()
<< std::endl;
}
和输出:
>>> import example
X
为了扩展这种方法,来自的访问者boost::python::def_visitor
将需要:
- 定义
__str__
和/或__repr__
作为一个函数,通常boost::python::object
通过o.__class__.__name__
.
- 提取并存储类名,然后定义
__str__
和/或__repr__
作为访问存储值的函数。
以下示例演示了这两种方法。
#include <boost/python.hpp>
/// @brief Helper type used to set and get a boost::python::class_
/// object's type name.
template <typename ClassT>
class typed_class_name
{
public:
/// @brief Extract and store the __name__ from a
/// boost::python::class_ objct.
static void set(const ClassT& c)
{
name_ = boost::python::extract<std::string>(c.attr("__name__"));
}
/// @brief Return the 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 get a 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 the 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())
;
}
以及用法:
>>> import example
>>> x = example.X()
>>> str(x)
typed
'X'
>>> repr(x)
generic
'X'