比方說,我都包裹着我的C++類Foo
和Bar
並可通過SWIG生成模塊wrap_py
從Python中訪問它們就好了Python類:返回繼承了基於C++的返回類型
// C++ class Bar { int i; Bar(int i) { this.i = i; } } class Foo { public: Foo(Bar* bar) { this.bar = bar; } Bar* GetBar() { return this.bar; } private: Bar* bar; }
在Python中,我創建我的用戶交互類是淺代理主要是添加的文檔字符串,並允許IDE做的參數名稱選項卡完成:
// Python class Bar(wrap_py.Bar): '''Some description ... Args: i (int): ... ''' def __init__(self, i): super(Bar, self).__init__(i) class Foo(wrap_py.Foo): '''Some description ... Args: bar (instance of Bar): ... ''' def __init__(self, bar): super(Foo, self).__init__(bar)
的問題是這裏Foo.GetBar()
,W HICH被自動地從C++類生成,返回wrap_py.Bar
類型,它不具有文檔字符串的痛飲實例,也沒有示出的參數名稱(大口暴露所有參數*args
)。相反,我想讓它提供我自己的淺代理Bar
。
那麼,我該如何告訴SWIG,自動返回Bar
而不是裸露的wrap_py.Bar
?
編輯:理想的情況下,這將返回類型Bar
是可能的,不僅是一個具體的函數簽名:
%feature("shadow") Foo::GetBar() %{ def bar(*args): result = $action result.__class__ = Bar return result %}
編輯2:我已經想出以下裝飾者,我需要在返回SWIG類型的每個函數/方法前面加上:
def typemap(f):
當然,這是不好的,並調用遺漏。
from functools import wraps @wraps(f) def wrapper(*args, **kwds): typemap = { wrap_py.Bar: Bar, # more types to come... } result = f(*args, **kwds) if isinstance(result, (tuple, list, set)): for r in result: r.__class__ = typemap.get(r.__class__, r.__class__) elif isinstance(result, dict): for k,v in result.items(): k.__class__ = typemap.get(k.__class__, k.__class__) v.__class__ = typemap.get(v.__class__, v.__class__) else: result.__class__ = typemap.get(result.__class__, result.__class__) return result return wrapper
您可以添加一個最小的完整示例來顯示失敗的位置?我不太瞭解你提出的問題,我認爲無論如何,這可能是一個簡單的解決方案。 – Flexo
絕對有可能,但我不確定這是否是正確的解決方案。我會盡量在本週晚些時候寫一個完整的答案。 – Flexo
@Flexo,對此有何更新? –