当前位置: 首页 > 面试题库 >

Cython:Python类包装器中的模板

卫皓
2023-03-14
问题内容

有没有一种方法可以为使用模板的Cython包装的C
++类创建Python包装器?(即完全按照此处显示的内容进行操作,但要使用模板:http :
//docs.cython.org/src/userguide/wrapping_CPlusPlus.html#create-cython-
wrapper-
class)。

我知道融合类型的变通方法(https://groups.google.com/forum/#!topic/cython-
users/qQpMo3hGQqI),但这不允许您实例化此类vector<vector<int>>:没有递归的概念。

改写

我想实现的是一个包装好的类:

cdef extern from "header.h":
    cdef cppclass Foo[T]:
        Foo(T param)
        # ...

创建一个简单的Python包装器:

cdef class PyFoo[T]:  # I know the '[T]' can't be here, it's a wish
    cdef Foo[T] *thisptr
    def __cinit__(self, param):
        self.thisptr = new Foo[T](param)
    # ...

我可以肯定Cython本身不支持该功能,但是也许有人可以想到一种解决方法。我不是在寻找惯用或不错的例子,我只是想知道这是否有可能。


问题答案:

正如您所说,Cython并不真正支持这一点。

我认为到目前为止,最简单的方法就是使用字符串替换手动生成一堆Cython文件。从“ foowrapper.pxi.src”文件(您想要的名称…)开始:

cdef class PyFoo_{T}:
  cdef Foo[{T}] *thisptr
  def __cinit__(self, param):
    self.thisptr = new Foo[{T}](param)
    # etc

接下来,通过一个简单的程序(也可能是Python)运行它以加载文件,进行字符串替换并以新名称再次保存文件。关键是:

output = code.format(T=T) # where T is a string with a C++ class name 
              # e.g. "int" or "std::vector<double>"

(显然,有一些关于加载和保存的代码已被我懒洋洋地跳过了)

然后,在您的Cython文件中,您只需“包括”每个类的生成文件。Cython中的“
include”命令是文字文本包含(如C预处理程序),并且需要一个.pxi文件:

cdef extern from "header.h":
    cdef cppclass Foo[T]:
        Foo(T param)
        # ...

include "foowrapper_int.pxi"
include "foowrapper_vectordouble.pxi
# etc

您必须选择在编译时生成的类,但这是不可避免的(模板是编译时功能),因此您将永远无法从Python脚本环境动态生成它们,因为赢得了相应的C ++类无法生成。

其他选择

其他几个选项值得简要考虑。首先,您可以继承不依赖于模板参数Foo<T>的基类(例如FooBase)。然后FooBase,您需要包装Cython(为您关心的情况生成类似构造函数的函数)。仅当要调用的函数没有依赖于模板类型的参数时,这才真正可行。显然,这还涉及更改C
++代码。

section选项用于查看另一种包装方式。Boost Python肯定会对此提供本地支持(但有其自身的缺点)。我想SIP /
SWIG也可以应付(但我不知道)。必要时,您可以将它们与Cython完美地混合搭配(通过导入包含模板类的生成模块)。



 类似资料:
  • 我想把C流包装在一个模板类中,这样所有 你能改变下面的代码,使它编译时不会改变整体意图吗? 我假设std::endl具有某种类型,因此被模板化方法“捕获”。

  • 本文向大家介绍Java Float包装器类,包括了Java Float包装器类的使用技巧和注意事项,需要的朋友参考一下 Float是提供的包装类,用于包装float基本值。 让我们创建一个带有float原语的Float对象。 现在让我们从字符串创建一个Float对象。 下面的示例显示了上面讨论的两种输出方法。 示例 输出结果

  • 是否有一种方法可以将Thymeleaf模板存储在与类相同的包中而不是或?例如,这样的结构: 为了实现这一点,我必须如何配置Spring和Thymeleaf?

  • 问题内容: 我知道包装器类是什么,它们将原始类型(例如int,double等)包装到各自类的对象中。 但是,为什么我们首先需要包装器类?为什么不简单地在我们拥有原始类型的地方使用它们呢? 问题答案: 几种可能的原因: 这样就可以有一个空值 包含在集合中 将一般/多态与其他对象一起视为对象

  • 问题内容: 我想在我们的管道库中添加和功能。我在Jenkins 文档中找到了: 我不知道如何向包装库中添加包装器,如下所示: 我们的工作流程如下所示: 因此,我想将时间戳和ansi-colors添加到库中的每个函数中。当然,我可以通过包装每个函数来做到这一点 但是它有点愚蠢。 那么我可以轻松地包装管道或库吗? 问题答案: 解决您的问题的一种方法是使用全局变量()。 要创建自己的构建步骤,请添加以下

  • 问题内容: 我有一段代码需要在方法中传递字段的类。由于代码的机制,我只能处理引用对象,而不能处理基元。我想要一种简单的方法来确定一个类型是否为原始类型,并将其与适当的包装器类交换。所以到目前为止,我在代码中所做的是这样的: 除我需要显式检查所有原始类型并将其与适当的包装器类交换外,该方法工作正常。现在我知道没有那么多原始类型,简单地将它们全部列出就不会有问题,但是我想知道是否有一种更简单,更优雅的