如何使用包装类的对象作为包装函数中的参数

2024-06-16 06:14:17 发布

您现在位置:Python中文网/ 问答频道 /正文

我使用Cython来包装C++代码并使其在Python中可用。我面临的问题是,我想在一个我也想包装的函数中使用包装类作为参数。因此,从Python的角度来看,我想创建和修改一个wrapped类的对象,并将其用作我也想从Python调用的wrapped函数的参数。下面的代码将很有希望演示这一点。你知道吗

下面你可以找到一个C++中的小例子,我想包装它:

./cppCode/Settings/Settings.h

class Settings
{
public:
  Settings();
  void doSomething();
};

./cppCode/Helper/Helper.h

#include "../Settings/Settings.h"

void myFunction(Settings settings);

功能其实并不重要。因此我遗漏了.cpp文件。以下是我目前在赛顿的做法:

./cythonCode/设置/设置.pxd你知道吗

cdef extern from "../../cppCode/Settings/Settings.h":
  cdef cppclass Settings:
    Settings() except +
    void doSomething()

./cythonCode/设置/设置.pyx你知道吗

# distutils: sources = ../../cppCode/Settings/Settings.cpp
# distutils: language = c++

from Settings cimport Settings

cdef class PySettings:
  cdef Settings c_settings

  def __cinit__(self):
    self.c_settings = Settings()

  def doSomething(self):
    self.c_settings.doSomething()

/cythonCode代码/助手.pxd你知道吗

from Settings.Settings cimport Settings

cdef extern from "../../cppCode/Helper/Helper.h":
  void myFunction(Settings settings)

/cythonCode代码/助手.pyx你知道吗

# distutils: sources = ../../cppCode/Helper/Helper.cpp
# distutils: language = c++

from Helper cimport myFunction

cdef PyMyFunction(PySettings settings):
  myFunction(settings)

你知道吗运行.py你知道吗

import cythonCode.Settings.Settings as Settings
#import cythonCode.Helper as Helper

mySettings = Settings.PySettings()
mySettings.doSomething()

#Helper.myFunction(mySettings) # not working

我希望这个项目的结构清晰。我真的很想助手.pyx“和”助手.pxd在一个文件夹“助手”以及但我不知道如何cimport设置。如果你能帮我解决这个问题,也将非常感谢。但是,主要的问题是让Helper运行,这样我就可以在运行.py". “这个”设置.py“构建cython模块的过程如下所示:

from distutils.core import setup
from Cython.Build import cythonize
from setuptools.extension import Extension

extensions = [
  Extension("Helper", ["Helper.pyx"])
]

setup(ext_modules=cythonize(extensions))

我在“设置”文件夹中分别执行相同的操作。你知道吗

我非常感谢你在解决这个问题上的帮助!你知道吗

编辑:如评论中所述,有两个错误:

1)应该是Helper.PyMyFunction文件(mySettings)在运行.py. 你知道吗

2)在PyMyFunction前面应该是def而不是cdef,因为我肯定想从Python调用这个函数。你知道吗

EDIT2:我仔细研究了您的意见,发现了一个不雅观的解决方案,这导致了另一个问题。下面是对我有效的代码:

你知道吗设置.pxd你知道吗

cdef extern from "../../cppCode/Settings/Settings.h":
  cdef cppclass Settings:
    Settings() except +
    void doSomething()

cdef extern from "../../cppCode/Helper/Helper.h":
  void myFunction(Settings settings)

你知道吗设置.pyx你知道吗

# distutils: sources = [../../cppCode/Settings/Settings.cpp, ../../cppCode/Helper/Helper.cpp]
# distutils: language = c++

from Settings cimport Settings, myFunction

cdef class PySettings:
  cdef Settings c_settings

  def __cinit__(self):
    self.c_settings = Settings()

  def doSomething(self):
    self.c_settings.doSomething()

def PyMyFunction(PySettings settings):
  myFunction(settings.c_settings)

当我用脑电波设置.pyx我可以运行以下Python代码,一切正常:

import Settings

mySettings = Settings.PySettings()
mySettings.doSomething()

Settings.PyMyFunction(mySettings)

我发现它的缺点是两个部分(设置和myFunction)都包含在同一个文件中。我不知道当这两个部分在不同的文件中时如何运行。你知道吗

EDIT3:为了解决“两个部分在不同的文件中”的问题,设想以下代码:

你知道吗设置.pxd你知道吗

cdef extern from "../../cppCode/Settings/Settings.h":
  cdef cppclass Settings:
    Settings() except +
    void doSomething()

你知道吗设置.pyx你知道吗

# distutils: sources = ../../cppCode/Settings/Settings.cpp
# distutils: language = c++

from Settings cimport Settings

cdef class PySettings:
  cdef Settings c_settings

  def __cinit__(self):
    self.c_settings = Settings()

  def doSomething(self):
    self.c_settings.doSomething()

你知道吗助手.pxd你知道吗

from Settings cimport Settings

cdef extern from "../../cppCode/Helper/Helper.h":
  void myFunction(Settings settings)

你知道吗助手.pyx你知道吗

# distutils: sources = ../../cppCode/Helper/Helper.cpp
# distutils: language = c++

from Helper cimport myFunction

def PyMyFunction(PySettings settings):
  myFunction(settings.c_settings)

它与EDIT2中的代码相同,但分为两个文件。只有一个额外的行助手.pxd即“从设置cimport设置”。然而,在助手.pyx我得到这个错误:

def PyMyFunction(PySettings settings):
                ^
---------------------------------------
Helper.pyx:6:17: 'PySettings' is not a type identifier

我尝试了“从设置cimport PySettings”,但这不起作用。同样的错误不断发生。所有文件都在同一目录中。你知道吗


Tags: fromselfhelpersettingsdef助手distutilspyx
1条回答
网友
1楼 · 发布于 2024-06-16 06:14:17

很明显,这个问题只是一系列小问题,其中有些问题已经非常接近解决了:

  1. 最初的主要问题是函数[应该是defcpdef,而不是cdef才能从Python调用 (Importing cython function: AttributeError: 'module' object has no attribute 'fun')。值得一提的是,Cython编译/加速了所有函数,cdefcpdef的唯一优点是可以从Cython调用它们稍微快一点。因此,默认情况下应该声明函数cdef

  2. <> >有几个例子,你使用C++类型名{{CD7}}代替Cython类^ {CD8}}。我想这很大程度上是一个拼写错误。

  3. 不需要在内部执行cimport Settings设置.pyx和cimport Helper在助手.pyx-Cython自动执行from filename cimport *的等效操作,其中存在一个具有匹配文件名的.pxd文件。

  4. 最后一个问题是将类划分为多个文件—您无法cimport PySettings到助手.pyx. 您应该记住的是,“^ {CD13}}”查看.pxd文件——将它处理成一个C/C++头。如果您想cimport PySettings,那么PySettings的声明必须在设置.pxd你知道吗

    cdef class PySettings:
       cdef Settings c_settings
       # signatures for any cdef functions also go here
    

    在设置.pyx你知道吗

    cdef class PySettings:
        # don't duplicate "cdef Settings c_settings"
        # do put all the def functions here
        def __cinit__(self):
           self.c_settings = Settings()
    
        def doSomething(self):
           self.c_settings.doSomething()
    

    从这个助手.pyx将知道PySettings以及它具有c_settings属性的事实。

相关问题 更多 >