我有嵌套在类中的类,并在c++中的命名空间内,格式如下:
namespace my_Namespace{
class MyFirstClass{
class NestedClass{
public:
NestedClass(int arg){};
NestedClass(double arg{};
NestedClass(std::string arg){};
};
};
};
从文档中导入cython中的类,如下所示:
cdef extern from "myfile.hpp" namespace "my_Namespace":
cdef cppclass MyFirstClass "my_Namespace::MyFirstClass"
cdef cppclass NestedClass "my_Namespace::MyFirstClass::NestedClass`
附带说明,我们是否需要导入cython脚本以使用cppclass?我不认为这是一个关键词。
无论如何,既然NestedClass
有构造函数重载,我该如何在cython中实现每一个?我正在尝试这样做,以便它可以在python中正常导入,我是否最好只制作整个c++命名空间和函数,并将它们放在DLL中,然后使用ctypes
导入和使用这些函数?
我看到的最后一个问题是,文档从上面的cython代码创建类,如下所示:
cdef class NestedClass:
cdef NestedClass* obj_
def __cinit__(self):
self.obj_=new NestedClass()
def __dealloc__(self): del self.obj_
这是正确的吗?我可以使用从C++文件中获得的NestClass
来派生类吗
`cdef class NestedClassInt:
cdef NestedClass* obj_
def __cinit__(self,arg:int): self.obj_=new NestedClass(arg)
#Now define the define the string one
def class NestedClassString:
cdef NestedClass* obj_
def __cinit__(self,arg:str): self.obj_=new NestedClass(arg)
我已经阅读了多个论坛,我知道python不支持构造函数重载,所以我不知道Cython是否支持,或者是否有方法从中转换。
正如我在评论中解释的那样,结果是您可以为C++方法声明重载,并且Cython能够理解它们。您不能为cdef类的方法声明重载,因此需要选择其他基于类型的切换方式。
我建议要么使用不同的工厂函数(classmethods/staticmethods(,要么在__init__
中使用isinstance
。
# distutils: language = c++
from libcpp.string cimport string as std_string
cdef extern from * namespace "my_Namespace":
"""
namespace my_Namespace{
class MyFirstClass{
public:
class NestedClass{
public:
NestedClass(int arg){};
NestedClass(double arg){};
NestedClass(std::string arg){};
};
};
};
"""
cdef cppclass MyFirstClass:
cppclass NestedClass:
NestedClass(int arg)
NestedClass(double arg)
NestedClass(std_string arg)
cdef class NestedClassWrapper:
cdef MyFirstClass.NestedClass* nc
def __dealloc__(self):
del self.nc
@classmethod # use staticmethod to make this cdef
def make_from_int(cls, int arg):
cdef NestedClassWrapper o = cls.__new__(cls)
o.nc = new MyFirstClass.NestedClass(arg)
return o
# and the same pattern for the int and string versions
cdef class NestedClassWrapper2:
cdef MyFirstClass.NestedClass* nc
def __dealloc__(self):
del self.nc
def __cinit__(self, arg):
if isinstance(arg, int):
# cast to a C int
self.nc = new MyFirstClass.NestedClass(<int>arg)
elif isinstance(arg, float):
self.nc = new MyFirstClass.NestedClass(<double>arg)
elif isinstance(arg, bytes):
self.nc = new MyFirstClass.NestedClass(<std_string>arg)
else:
raise TypeError
关于这个主题的其他变体也可能存在。例如,将融合类型作为__cinit__
的参数,或者使用try: ... except
而不是isinstance
来测试类型转换。但大多数解决方案看起来都像这两种方法中的一种。
.pyx
,则应识别cppclass
。不过,您的编辑器可能不会突出显示它。