gpt4 book ai didi

python - Swig 和 Python - 不同的对象实例化

转载 作者:太空宇宙 更新时间:2023-11-03 19:03:55 24 4
gpt4 key购买 nike

我有一个关于在 Python 端生成的 swig 包装对象和在 C++ 端生成的包装对象的问题。假设我有以下简单的 C++ 类定义

#include <vector>

class Sphere
{
public:
Sphere(){};
};

class Container
{
public:
Container() : data_(0) {};

void add() {
data_.push_back(Sphere());
}

Sphere & get(int i) { return data_[i]; }

std::vector<Sphere> data_;
};

以及以下 swig 设置

%module engine
%{
#define SWIG_FILE_WITH_INIT
#include "sphere.h"
%}

// -------------------------------------------------------------------------
// Header files that should be parsed by SWIG
// -------------------------------------------------------------------------
%feature("pythonprepend") Sphere::Sphere() %{
print 'Hello'
%}
%include "sphere.h"

如果我然后在 Python 中执行以下操作

import engine
sphere_0 = engine.Sphere()
container = engine.Container()
container.add()
sphere_1 = container.get(0)

然后,包装的 Sphere 类的第一个实例会调用 Python 包装接口(interface)的 init 方法(打印“Hello”)。

但是,第二个实例是在 C++ 端生成的,但没有(不打印“Hello”)。

由于我的目标是能够在构造对象时向其添加额外的 Python 功能,因此我很高兴听到是否有人能提供任何关于实现此目的的正确方法的指示 - 对于上述两种实例化场景。

最诚挚的问候,

疯狂

最佳答案

我通常使用接口(interface)文件中的显式 pythoncode block 执行类似的操作:

%pythoncode %{
def _special_python_member_function(self):
print "hello"
self.rotate() # some function of Sphere
Sphere.new_functionality=_special_python_member_function
%}

因此,除了 SWIG 接口(interface)提供的功能之外,您还可以向该类添加任意 Python 功能。您可能想要/需要重命名一些 C 功能,但这应该可以让您获得您想要的所有成员函数

我从未尝试过以这种方式重新映射__init__,所以我不知道它会如何表现。假设它不起作用,您将无法确保 python 对象在构造时具有给定的内部状态(成员变量)。

您将被迫做的是进行惰性评估:

def function_that_depends_on_python_specific_state(self, *args):
if not hasatttr( self, 'python_data'):
self.python_data = self.make_python_data() # construct the relevant data
pass # do work that involves the python specific data

并检查Python特定数据是否存在。如果只有少数情况其中,我只是将其放入上面的函数中。然而,如果这最终成为困惑,你可以修改 __getattr__ 以便它构造 python 特定的数据访问时的成员。

def _sphere_getattr(self, name):
if name=='python_data':
self.__dict__[name]=self.make_python_data()
return self.__dict__[name]
else:
raise AttributeError
Sphere.__getattr__ = _sphere_getattr

恕我直言,在您拥有大量新功能和独立于底层 C 实现的数据的情况下,您实际上是在问“如何使我的 python Sphere 类成为 C 的子类”球体类但保持它们相同的类型?”

关于python - Swig 和 Python - 不同的对象实例化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15260000/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com