Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/wix/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用PyCxx创建可继承的Python类型 我和朋友最近一直在忙于各种Python C++包装,试图找到一个既满足专业又有兴趣项目的需求。我们都在努力在轻量级和易于接口之间找到一个很好的平衡点,同时隐藏了Python C api中最丑陋的部分。然而,PyCxx在公开类型时并不十分健壮(即:它指示您创建类型工厂而不是实现构造函数),我们一直在努力填补空白,以便以更有效的方式公开类型。为了填补这些空白,我们转向C api_Python_Python C Api_Pycxx - Fatal编程技术网

使用PyCxx创建可继承的Python类型 我和朋友最近一直在忙于各种Python C++包装,试图找到一个既满足专业又有兴趣项目的需求。我们都在努力在轻量级和易于接口之间找到一个很好的平衡点,同时隐藏了Python C api中最丑陋的部分。然而,PyCxx在公开类型时并不十分健壮(即:它指示您创建类型工厂而不是实现构造函数),我们一直在努力填补空白,以便以更有效的方式公开类型。为了填补这些空白,我们转向C api

使用PyCxx创建可继承的Python类型 我和朋友最近一直在忙于各种Python C++包装,试图找到一个既满足专业又有兴趣项目的需求。我们都在努力在轻量级和易于接口之间找到一个很好的平衡点,同时隐藏了Python C api中最丑陋的部分。然而,PyCxx在公开类型时并不十分健壮(即:它指示您创建类型工厂而不是实现构造函数),我们一直在努力填补空白,以便以更有效的方式公开类型。为了填补这些空白,我们转向C api,python,python-c-api,pycxx,Python,Python C Api,Pycxx,然而,这给我们留下了一些问题,api文档似乎没有涵盖太多的深度(当它涵盖时,答案有时会相互矛盾)。基本的首要问题很简单:Python类型作为基本类型必须定义什么?我们发现,为了使PyCxx类作为一种类型发挥作用,我们需要显式定义tp_new和tp_dealloc,并将该类型设置为模块属性,我们需要在[our type]->tp_flags上设置Py_TPFLAGS_BASETYPE,但除此之外,我们仍在摸索 以下是我们迄今为止的代码: class kitty : public Py::Pytho

然而,这给我们留下了一些问题,api文档似乎没有涵盖太多的深度(当它涵盖时,答案有时会相互矛盾)。基本的首要问题很简单:Python类型作为基本类型必须定义什么?我们发现,为了使PyCxx类作为一种类型发挥作用,我们需要显式定义tp_new和tp_dealloc,并将该类型设置为模块属性,我们需要在[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();
}
奇怪的是,如果您注释掉所有meanKitty位,脚本会运行,猫会发出喵喵声,但是如果您突然取消注释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
回溯(最近一次呼叫最后一次):
文件“d:\Development\Junk Projects\PythonCxx\Toji.py”,第12行,在
卑鄙的基蒂
属性错误:划痕

所以仍然在寻求帮助!谢谢

我只对PyCxx做了一点点工作,我不是一个编译器,但我怀疑您看到的情况与以下情况类似,如纯Python所示:

>>> class C(object):
...   def __getattribute__(self, key):
...     print 'C', key
... 
>>> class D(C):
...   def __init__(self):
...     self.foo = 1
... 
>>> D().foo
C foo
>>> 
<>我最好的猜测是,C++ <代码> GATTARC < /Cord>方法应该检查<代码> .OBY-Type > TPYDICT< /CUT>(当然,它是子类的DICT,如果<代码>这个<代码>子类的实例),并且只调用调用<代码> GETAtTraseMedio> <代码>,如果您在那里找不到代码>名称< />代码(参见PyDISMIAPI函数)。
另外,我认为您不应该自己设置
tp\u dealloc
:我看不出您的实现如何改进PyCxx的默认
扩展对象\u deallocator

您必须将
kitty
声明为
类新样式\u类:public Py::PythonClass
。请参阅
simple.cxx
和位于的Python测试用例


Python2.2引入了新样式的类,这些类允许用户对内置类型(比如新的内置类型)进行子类化。继承在您的示例中不起作用,因为它定义了一个旧样式的类。

您在pylibcat++上工作吗?
>>> class C(object):
...   def __getattribute__(self, key):
...     print 'C', key
... 
>>> class D(C):
...   def __init__(self):
...     self.foo = 1
... 
>>> D().foo
C foo
>>>