在C++/Cython中,是否可以只声明相关属性在Python中可见



假设我有一个.h文件,其中包含以下代码:

class MyClass
{
public:
int Attribute1;
int Attribute2;
MyClass(){};
virtual ~MyClass(){};
virtual void Method1(string var1);
virtual float Method2(float var2);
};

和一个相关的.pyx文件:

cdef class PyClass:
cdef MyClass *classptr
[standard __cinit__ and __dealloc__ declarations ]
cdef int Attribute1;
def Method1(self, var1):
self.classptr.Method1(var1)

和pxd文件,带有:

cdef extern from "mycode.h":
cdef cppclass MyClass:
MyClass() except +
int Attribute1
void Method1(string)

我使用setup.py创建了一个.so库,以便在python模块中导入。

请注意,尽管c++中存在MyClass::Method2和MyClass::Attribute2,但我在Cython中没有提到它们,因此它们在.so库中不可见。也许我这样做是因为它们被MyClass::Method1((间接使用,或者只是因为我不打算在python代码中调用它们。

这是一种可能导致问题/怪异行为的不良做法吗?如果是,为什么?

cdef class PyClass:
cdef MyClass *classptr
# ...
cdef int Attribute1;

Attribute1不会按照你的想法行事。它是作为PyClass的一部分存储的单独值,与classptr中的Attribute1无关。你可能想写一个属性。


然而,要回答您的问题:

是的,你可以只包装你感兴趣的特定函数。Cython不需要知道C++类的所有细节,它只需要知道足够的细节,就可以使用它们生成有效的C++代码。省略一些有用的快速例子:

  • 模板。例如,std::string实际上是一个模板typedef,但Cython包装器可能不一定知道这一点,或者可选的分配器模板类型,或者Cython并不真正支持的数字模板类型。

  • 复杂的继承层次结构:您关心的函数是否真的来自基类并不重要。只需包装您正在使用的派生类。

  • 返回其他类的接口-因为这样你就需要包装第二个类(这可能会暴露第三个类…(

除了不能调用尚未从python中封装的代码之外,真的没有任何后果。Cython的C++支持有些不完整(而且可能永远都是(,通常需要给它一个简化的C++接口来完成任何事情。

最新更新