使用boost.python,如何扩展类的__dir__函数?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用boost.python,如何扩展类的__dir__函数?相关的知识,希望对你有一定的参考价值。
我有一个类导出到python,在纯python中,我可以通过这个轻松扩展dir函数:
def __dir__(self):
attr = list(self.__attributesMap().keys())
return attr + dir(type(self))
所以我在我的c ++类中添加了一个dir函数,但问题是如何用boost.python在c ++中获取dir(type(self))
的值?
答案
不幸的是,我不认为这是可能的。我们可以部分宣布这个类:
struct test {
void foo() { printf("foo!
"); }
void bar() { printf("bar!
"); }
void baz() {}
};
// define initial tclass
auto tclass = class_<test>("test")
.def("foo", &test::foo)
.def("bar", &test::bar);
然后扩展dir函数:
auto cur = tclass();
tclass.def("__dir__",
make_function(
[cur] (object) -> object {
list curdir = (list)object(handle<>(PyObject_Dir(cur.ptr())));
curdir.append("hello");
return curdir;
},
default_call_policies(),
boost::mpl::vector<object, object>()));
但是,这样做,使用对象本身的实例,我们得到一个无限循环,因为它只是重新绑定内部指针。如果我们尝试调用PyObject_Type并在其上调用PyObject_Dir,我们将返回Boost.Python.class,因为它是boost :: python公开类的实际类型,并且它没有添加正确的对象(因为这是动态完成的)。
如果我们查看python,我们可以看到这个:
>>> dir(skunk.test)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__instance_size__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'bar', 'foo']
>>> dir(type(skunk.test))
['__abstractmethods__', '__base__', '__bases__', '__basicsize__', '__call__', '__class__', '__delattr__', '__dict__', '__dictoffset__', '__doc__', '__eq__', '__flags__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__instancecheck__', '__itemsize__', '__le__', '__lt__', '__module__', '__mro__', '__name__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasscheck__', '__subclasses__', '__subclasshook__', '__weakrefoffset__', 'mro']
班级的类型不是我们想要的。所以你不能使用类本身(无限循环),你不能使用类型(不是像我们在Python中习惯的类型),还剩下什么?您可以将该类定义两次,并使用一个来提供另一个的dir,但这似乎是多余的。最好只需手动编写dir函数来硬编码类上的其他方法。无论如何你必须手动.def()。
以上是关于使用boost.python,如何扩展类的__dir__函数?的主要内容,如果未能解决你的问题,请参考以下文章
无法在 Boost.Python 中使用 __stdcall 编译示例