3

Is there a standardized (or commonly accepted way) to tackle the issue of not being able to overload __cinit__ methods in cython when wrapping C++ classes?

There is the possibility of making __cinit__ take *args and **kwargs to contain parameters and inside the __cinit__ scope select the way to generate the C++ instance according to certain pattern. This approach however has complications:

  • Trying to identify the correct constructor from the arguments might be dangerous in certain circumstances unless the arguments are named and passed as kwargs which might become cumbersome for users.
  • When the arguments are not invoked by their type in the __cinit__ argument list, they are passed as Python objects. In my working case, the arguments are Python wrappers for C++ classes, and trying to retrieve these instances "thisptr" is a task of the devil when they are passed as Python objects from the *args or **kwargs.
  • The implied need of using a sequence of if... elif... else cases to select a C++ constructor from the argument combination ultimately becomes quite messy.

So there has to be a better way. One way may be using the classmethod approach (e.g. see: classmethod to overload __init__ behavior in Python). Nevertheless, as far as I know (and please correct me if I'm wrong), classmethod implies invoking methods with names different of the class name and this does not resemble well the C++ way of constructing instances with just one class name.

Any ideas on this?

4

1 回答 1

2

就个人而言,我会使用类方法。

WrapperClass.fromSpambar(spambar)

这不是那个令人费解的恕我直言。如果你不能在 C++ 中重载函数,你也需要回退到这种方法。

如果您可以在初始化时接受一些重量级的操作,您可以通过定义“模式”或类似的方法来实现一种方法来识别构造函数的调用方式。即 args 和 kwargs 的正则表达式。;)

我没有看到从 Python 对象获取thisptr的问题。

cdef WrapperClass wrpclsi
if isinstance(instance, WrapperClass):
    wrpclsi = instance
else:
    raise TypeError('expected instance of WrapperClass.')

cdef WrappedClassFromCpp* thisptr = wrpclsi.thisptr 
于 2012-06-09T10:31:26.713 回答