然而,这给我们留下了一些问题,api文档似乎并没有很深入地涵盖这些问题(如果有,答案有时会相互矛盾)。基本的首要问题很简单:要使Python类型作为基类型运行,必须定义什么?我们发现,为了让PyCxx类作为一个类型来工作,我们需要显式地定义tp_new和tp_dealoc,并将类型设置为module属性,我们需要在[our type]->;tp峎flags上设置Py_TPFLAGS_BASETYPE,但除此之外,我们仍在黑暗中摸索。在
以下是迄今为止我们的代码:
class kitty : public Py::PythonExtension<kitty> {
public:
kitty() : Py::PythonExtension<kitty>() {}
virtual ~kitty() {}
static void init_type() {
behaviors().name("kitty");
add_varargs_method("speak", &kitty::speak);
}
static PyObject* tp_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds) {
return static_cast<PyObject*>(new kitty());
}
static void tp_dealloc(PyObject *obj) {
kitty* k = static_cast<kitty*>(obj);
delete k;
}
private:
Py::Object speak(const Py::Tuple &args) {
cout << "Meow!" << endl;
return Py::None();
}
};
// cat Module
class cat_module : public Py::ExtensionModule<cat_module> {
public:
cat_module() : Py::ExtensionModule<cat_module>("cat") {
kitty::init_type();
// Set up additional properties on the kitty type object
PyTypeObject* kittyType = kitty::type_object();
kittyType->tp_new = &kitty::tp_new;
kittyType->tp_dealloc = &kitty::tp_dealloc;
kittyType->tp_flags |= Py_TPFLAGS_BASETYPE;
// Expose the kitty type through the module
module().setAttr("kitty", Py::Object((PyObject*)kittyType));
initialize();
}
virtual ~cat_module() {}
};
extern "C" void initcat() {
static cat_module* cat = new cat_module();
}
我们的Python测试代码如下所示:
^{pr2}$有趣的是,如果您将所有meanKitty位注释掉,脚本会运行,cat会喵喵叫,但是如果您取消注释meanKitty类,Python会突然给出以下信息:
AttributeError: 'kitty' object has no attribute 'speak'
把我搞糊涂了。好像从它继承就完全隐藏了基类!如果有人能提供一些关于我们缺失什么的见解,我们将不胜感激!谢谢!在
编辑:好吧,在发布这篇文章五秒钟后,我想起了我们之前想尝试的一些东西。我给kitty添加了以下代码-
virtual Py::Object getattr( const char *name ) {
return getattr_methods( name );
}
现在我们用Python叫唤两只小猫!但还没有完全实现,因为现在我明白了:
Traceback (most recent call last):
File "d:\Development\Junk Projects\PythonCxx\Toji.py", line 12, in <module>
meanKitty.scratch()
AttributeError: scratch
所以仍然在寻求帮助!谢谢!在
我只对PyCxx做了一点工作,我不在编译器工作,但我怀疑您所看到的与以下情况类似,如用纯Python表示的:
我最好的猜测是,C++ ^ {< CD1>}方法应该检查^ {< CD2>}(当然,它将是子类的DICT,如果^ {CD3>}是子类的实例),并且如果在那里找不到^ {CD5>}(请参阅PyDISMIAPI函数),只调用^ {CD4>}。在
另外,我不认为您应该自己设置
tp_dealloc
:我看不出您的实现在PyCxx的默认extension_object_deallocator
上有什么改进。在必须将
kitty
声明为class new_style_class: public Py::PythonClass< new_style_class >
。请参见simple.cxx
和位于{a1}的Python测试用例。在Python2.2引入了一些新的类,这些类允许用户对内置类型进行子类化(比如新的内置类型)。继承在您的示例中不起作用,因为它定义了一个旧样式的类。在
相关问题 更多 >
编程相关推荐