c++ - Python 属性和 Swig

标签 c++ python properties swig

我正在尝试使用 swig 为一些 C++ 代码创建 python 绑定(bind)。我似乎遇到了一个问题,试图从我拥有的一些访问器函数创建 python 属性,如下所示:

class Player {
public:
  void entity(Entity* entity);
  Entity* entity() const;
};

我尝试使用 python 属性函数创建一个属性,但似乎 swig 生成的包装类与它不兼容,至少对于 setter 而言。

如何使用 swig 创建属性?

最佳答案

有一种简单的方法可以从 swig 方法中创建 python 属性。
假设 C++ 代码 Example.h:

C++ header

class Example{
    public:
      void SetX(int x);
      int  GetX() const;
    };

让我们将此 setter 和 getter 转换为 python 属性“x”。诀窍在于 .i 文件。我们添加了一些“swiggy”内联 Python 代码(使用 %pythoncode),这些代码插入到生成的 Python 类的主体中(在自动生成的 Python 代码中)。

Swig 包装 Example.i

%module example
%{
     #include "example.h"
%}

class Example{
    public:
      void SetX(int x);
      int  GetX() const;

      %pythoncode %{
         __swig_getmethods__["x"] = GetX
         __swig_setmethods__["x"] = SetX
         if _newclass: x = property(GetX, SetX)
      %}
    };

查看python代码:

python 测试代码

import example

test = example.Example()
test.x = 5
print "Ha ha ha! It works! X = ", repr(test.x)

就是这样!



让它更简单!

无需重写类定义。感谢 Joshua 的建议,可以使用 SWIG 指令 %extend ClassName { }。

Swig 包装 Example.i

%module example
%{
     #include "example.h"
%}

%extend Example{
      %pythoncode %{
         __swig_getmethods__["x"] = GetX
         __swig_setmethods__["x"] = SetX
         if _newclass: x = property(GetX, SetX)
      %}
    };

隐藏 setter 和 getter 函数

正如大家所见,test.GetX() 和 test.SetX() 在转换后仍然存在。可以通过以下方式隐藏它们:

a) 使用 %rename 重命名函数,在开头添加“_”,从而使 python 的方法“私有(private)”。在 SWIG 界面 .i 例子.i

...
class Example{
   %rename(_SetX) SetX(int);
   %rename(_GetX) GetX();
...

(%rename 可以放在某个单独的地方,以节省将此类转换为不需要这些'_'的其他语言的可能性)

b) 或者可以使用 %feature("shadow")

为什么会这样?

为什么我们必须使用这些东西通过 SWIG 将方法转换为属性? 如前所述,SWIG 自私地覆盖了 _setattr_,因此必须使用 _swig_getmethods__swig_setmethods_ 进行注册功能并保持在swig方式。

为什么人们更喜欢这种方式?

上面列出的方法,尤其是使用 PropertyVoodoo 的方法是……就像烧房子煎鸡蛋一样。它还破坏了类布局,因为必须创建继承的类才能从 C++ 方法中创建 python 属性。我的意思是如果类Cow返回类Milk并且继承类是MilkWithProperties(Milk),如何让Cow产生MilkWithProperties?

这种方法允许人们:

  1. 明确控制要转换为 python 属性的 C++ 方法
  2. 转换规则位于 swig interface(*.i) 文件中,它们应该在的地方
  3. 一个自动生成的 .py 文件
  4. 在 swig 生成的 .py 文件中保持插入的 swig 语法
  5. 如果将库包装成其他语言,则忽略%pythoncode

更新 在较新的版本中,SWIG 放弃了 _swig_property,因此只需使用 property。它与旧版本的 swig 相同。我已经换了帖子。

关于c++ - Python 属性和 Swig,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1183716/

相关文章:

c# - 在运行时,如何测试属性是否为只读?

c# - 我检查了 INotifyPropertyChanged 但如何利用它?

iphone - objective-c : i want the automatic memory management of properties, 但无法从其他类访问

c++ - HEAP 错误 指定给 RtlValidateHeap 的地址无效

c++ - 将C++代码编译成汇编然后反汇编

python - 在Python中,如何根据扩展名从文本文件中提取文件名并将其放入新的文本文件中?

python - 如何按键对字典进行排序?

c++ - OpenCV - 使用 calcHist 混淆

c++ - 如何创建一个从两侧都可见的四边形?

python - 如何将 2D 网格化点云插值到连续区域?