有没有办法扩展swig / python中的所有类?

时间:2014-02-10 23:20:24

标签: python swig

我有很多C / C ++类要使用Swig导出到python。我注意到默认情况下,Swig不为包装类生成__hash__方法,因此使用默认哈希,即包装器对象的id(即其内存地址或类似内容)。这意味着如果我最终得到两个包含相同C对象的python对象,它们会在dicts中以不同的方式进行散列等等,这很奇怪并导致难以发现的错误。

我可以使用更好的__hash__

轻松扩展任何课程
%extend Foo {
   bool __eq__(const Foo &other) { return $self == &other; }
   bool __ne__(const Foo &other) { return $self != &other; }
   long __hash__() { return (long) $self; } // hash: just address of C struct
}

(我也认为eq应默认基于C结构地址进行比较,而不是包装器的地址。)

我的问题是:有没有办法告诉Swig扩展这样的所有类?或者我必须一次做一个?

我想第二个问题是:为什么不自动执行此操作?默认行为有用吗?我发现它不是。

1 个答案:

答案 0 :(得分:5)

我不知道有办法做到这一点,只是因为它很少是你想要的(“所有课程”可能包括的比你意识到的更多并且真的有意)。但是,SWIG确实支持自己的宏系统,因此您可以执行以下操作:

%define PY_HASHABLE(TypeName)
%extend TypeName {
   bool __eq__(const TypeName &other) { return $self == &other; }
   bool __ne__(const TypeName &other) { return $self != &other; }
   long __hash__() { return (long) $self; } // hash: just address of C struct
}
%enddef

然后你会做

#if defined(SWIGPYTHON) 
PY_HASHABLE(Foo)
PY_HASHABLE(Bar)
#endif

等。您可以为给定的类具有多个扩展子句,因此上述内容不会干扰其他扩展。