Cython cdef Class 不显示文档字符串或 __init__ 参数
Cython cdef Class not displaying doc string or __init__ parameters
我已经使用 cdef 定义了一个 python class,它用 Cython 包装了一个 C++ class 并且它工作正常。但是,当我在 python 或 class 中使用 help(class) 时?在 ipython 中,我得到如下内容:
>>> TestClass.CTestClass?
Init signature: TestClass.CTestClass()
Docstring: <no docstring>
File: ~/Coding/CythonWithCppTutorials/ClassCythonCPPWithMemberFunctions/TestClass.so
Type: type
它不显示我想显示的任何文档字符串或初始化签名,我怎样才能让它显示这个?
Cython包装器如下:
TestClass.pyx
import cython
import numpy as np
cimport numpy as np
cdef extern from "TestClassC.cpp": # defines the source C++ file
cdef cppclass TestClass: # says that there is a class defined in the above C++ file called TestClass
TestClass(int Dimensionality, double* InputArray) # the class has public member function TestClass which takes some arguments
double SumListOfNumbers() # the class has a public member function which returns a double and has no arguments
int Dimensionality # the class has a public variable that is an integer and is called Dimensionality
double* ListOfNumbers # the class has another public variable that is a pointer to a double
cdef class CTestClass: # defines a python wrapper to the C++ class
"""
This is a test class wrapper for c++.
"""
cdef TestClass* thisptr # thisptr is a pointer that will hold to the instance of the C++ class
def __cinit__(self, int Dimensionality, np.ndarray[double, ndim=1, mode="c"] InputArray not None): # defines the python wrapper class' init function
cdef double[::1] InputArrayC = InputArray # defines a memoryview containnig a 1D numpy array - this can be passed as a C-like array by providing a pointer to the 1st element and the length
self.thisptr = new TestClass(Dimensionality, &InputArrayC[0]) # creates an instance of the C++ class and puts allocates the pointer to this
def __dealloc__(self): # defines the python wrapper class' deallocation function (python destructor)
del self.thisptr # destroys the reference to the C++ instance (which calls the C++ class destructor
def CSumListOfNumbers(self):
return self.thisptr.SumListOfNumbers()
C++ 代码如下所示:
TestClassC.cpp
#include <iostream>
class TestClass{
public:
TestClass(int Dimensionality, double* InputArray); // prototype of constructor
~TestClass(void); // prototype of destructor
double SumListOfNumbers(void);
int Dimensionality;
double* ListOfNumbers;
};
TestClass::TestClass(int DIM, double* InputArray)
{
Dimensionality = DIM;
std::cout << Dimensionality << "\n";
ListOfNumbers = new double[Dimensionality];
for (int i = 0; i < Dimensionality; ++i) {
ListOfNumbers[i] = InputArray[i];
std::cout << ListOfNumbers[i] << ", ";
}
std::cout << "\n";
};
TestClass::~TestClass(void){
std::cout << "Being Destroyed" << "\n";
};
double TestClass::SumListOfNumbers(void){
double Sum = 0;
for (int i = 0; i < Dimensionality; ++i) {
Sum += ListOfNumbers[i];
}
return Sum;
}
解决这个问题的方法是按照 oz1 的建议将 embedsignature
指令设置为 True
并添加一个正常的 python __init__
函数像这样:
@cython.embedsignature(True)
cdef class CTestClass: # defines a python wrapper to the C++ class
"""
This is a test class wrapper for c++.
"""
def __init__(self, Dimensionality, InputArray):
pass
cdef TestClass* thisptr # thisptr is a pointer that will hold to the instance of the C++ class
def __cinit__(self, int Dimensionality, np.ndarray[double, ndim=1, mode="c"] InputArray not None): # defines the python wrapper class' init function
cdef double[::1] InputArrayC = InputArray # defines a memoryview containnig a 1D numpy array - this can be passed as a C-like array by providing a pointer to the 1st element and the length
self.thisptr = new TestClass(Dimensionality, &InputArrayC[0]) # creates an instance of the C++ class and puts allocates the pointer to this
然后初始化签名会自动包含在文档字符串中,如下所示:
In [1]: import TestClass
In [2]: TestClass.CTestClass?
Init signature: TestClass.CTestClass(self, /, *args, **kwargs)
Docstring:
CTestClass(Dimensionality, InputArray)
This is a test class wrapper for c++.
File: ~/Coding/CythonWithCppTutorials/ClassCythonCPPWithMemberFunctions/TestClass.so
Type: type
我已经使用 cdef 定义了一个 python class,它用 Cython 包装了一个 C++ class 并且它工作正常。但是,当我在 python 或 class 中使用 help(class) 时?在 ipython 中,我得到如下内容:
>>> TestClass.CTestClass?
Init signature: TestClass.CTestClass()
Docstring: <no docstring>
File: ~/Coding/CythonWithCppTutorials/ClassCythonCPPWithMemberFunctions/TestClass.so
Type: type
它不显示我想显示的任何文档字符串或初始化签名,我怎样才能让它显示这个?
Cython包装器如下:
TestClass.pyx
import cython
import numpy as np
cimport numpy as np
cdef extern from "TestClassC.cpp": # defines the source C++ file
cdef cppclass TestClass: # says that there is a class defined in the above C++ file called TestClass
TestClass(int Dimensionality, double* InputArray) # the class has public member function TestClass which takes some arguments
double SumListOfNumbers() # the class has a public member function which returns a double and has no arguments
int Dimensionality # the class has a public variable that is an integer and is called Dimensionality
double* ListOfNumbers # the class has another public variable that is a pointer to a double
cdef class CTestClass: # defines a python wrapper to the C++ class
"""
This is a test class wrapper for c++.
"""
cdef TestClass* thisptr # thisptr is a pointer that will hold to the instance of the C++ class
def __cinit__(self, int Dimensionality, np.ndarray[double, ndim=1, mode="c"] InputArray not None): # defines the python wrapper class' init function
cdef double[::1] InputArrayC = InputArray # defines a memoryview containnig a 1D numpy array - this can be passed as a C-like array by providing a pointer to the 1st element and the length
self.thisptr = new TestClass(Dimensionality, &InputArrayC[0]) # creates an instance of the C++ class and puts allocates the pointer to this
def __dealloc__(self): # defines the python wrapper class' deallocation function (python destructor)
del self.thisptr # destroys the reference to the C++ instance (which calls the C++ class destructor
def CSumListOfNumbers(self):
return self.thisptr.SumListOfNumbers()
C++ 代码如下所示:
TestClassC.cpp
#include <iostream>
class TestClass{
public:
TestClass(int Dimensionality, double* InputArray); // prototype of constructor
~TestClass(void); // prototype of destructor
double SumListOfNumbers(void);
int Dimensionality;
double* ListOfNumbers;
};
TestClass::TestClass(int DIM, double* InputArray)
{
Dimensionality = DIM;
std::cout << Dimensionality << "\n";
ListOfNumbers = new double[Dimensionality];
for (int i = 0; i < Dimensionality; ++i) {
ListOfNumbers[i] = InputArray[i];
std::cout << ListOfNumbers[i] << ", ";
}
std::cout << "\n";
};
TestClass::~TestClass(void){
std::cout << "Being Destroyed" << "\n";
};
double TestClass::SumListOfNumbers(void){
double Sum = 0;
for (int i = 0; i < Dimensionality; ++i) {
Sum += ListOfNumbers[i];
}
return Sum;
}
解决这个问题的方法是按照 oz1 的建议将 embedsignature
指令设置为 True
并添加一个正常的 python __init__
函数像这样:
@cython.embedsignature(True)
cdef class CTestClass: # defines a python wrapper to the C++ class
"""
This is a test class wrapper for c++.
"""
def __init__(self, Dimensionality, InputArray):
pass
cdef TestClass* thisptr # thisptr is a pointer that will hold to the instance of the C++ class
def __cinit__(self, int Dimensionality, np.ndarray[double, ndim=1, mode="c"] InputArray not None): # defines the python wrapper class' init function
cdef double[::1] InputArrayC = InputArray # defines a memoryview containnig a 1D numpy array - this can be passed as a C-like array by providing a pointer to the 1st element and the length
self.thisptr = new TestClass(Dimensionality, &InputArrayC[0]) # creates an instance of the C++ class and puts allocates the pointer to this
然后初始化签名会自动包含在文档字符串中,如下所示:
In [1]: import TestClass
In [2]: TestClass.CTestClass?
Init signature: TestClass.CTestClass(self, /, *args, **kwargs)
Docstring:
CTestClass(Dimensionality, InputArray)
This is a test class wrapper for c++.
File: ~/Coding/CythonWithCppTutorials/ClassCythonCPPWithMemberFunctions/TestClass.so
Type: type