Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>There is an easy way to make python properties from methods with swig.<br> Suppose C++ code Example.h:</p> <p><strong>C++ header</strong></p> <pre><code>class Example{ public: void SetX(int x); int GetX() const; }; </code></pre> <p>Lets convert this setter and getter to python propery 'x'. The trick is in .i file. We add some "swiggy" inline python code (with %pythoncode) that is inserted in a body of a resulting python class (in the auto-generated python code).</p> <p><strong>Swig wrapping Example.i</strong></p> <pre><code>%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) %} }; </code></pre> <p>Check the python code:</p> <p><strong>python test code</strong></p> <pre><code>import example test = example.Example() test.x = 5 print "Ha ha ha! It works! X = ", repr(test.x) </code></pre> <p>That is it!</p> <hr> <hr> <h2>Make it simplier!</h2> <p>There is no need to rewrite a class definition. Thanks to Joshua advice, one could use SWIG directive %extend ClassName { }. </p> <p><strong>Swig wrapping Example.i</strong></p> <pre><code>%module example %{ #include "example.h" %} %extend Example{ %pythoncode %{ __swig_getmethods__["x"] = GetX __swig_setmethods__["x"] = SetX if _newclass: x = property(GetX, SetX) %} }; </code></pre> <h2>Hiding setter and getter functions</h2> <p>As one may see, test.GetX() and test.SetX() are still in place after conversion. One can hide them by:</p> <p>a) Rename functions by using %rename, add '_' in the beginning thus making methods "private" for python. In the a SWIG interface .i Example.i</p> <pre><code>... class Example{ %rename(_SetX) SetX(int); %rename(_GetX) GetX(); ... </code></pre> <p>(%rename may be placed in some separated place to save the possibility to convert this class to other languages, which don't need these '_')</p> <p>b) or one can play with %feature("shadow")</p> <h2>Why is it so?</h2> <p>Why do we have to use such things to convert methods to a property by using SWIG? As it was said, SWIG selfishly overrides <strong>_<em>setattr</em>_</strong>, so one have to use <strong>_swig_getmethods_</strong> and <strong>_swig_setmethods_</strong> to register functions and stay in the swig way. </p> <h2>Why may one prefer this way?</h2> <p>The methods listed above, especially with PropertyVoodoo are... It is like burning the house to fry an egg. Also it breaks the classes layout, as one have to create inherited classes to make python properties from C++ methods. I mean if class Cow returns class Milk and the inherited class is MilkWithProperties(Milk), how to make Cow to produce MilkWithProperties?</p> <p>This approach allows one to:</p> <ol> <li><strong>explicitly control what C++ methods to convert to python properties</strong></li> <li>conversion rules are located in swig interface(*.i) files, the place where they are supposed to be</li> <li>one resulting autogenerated .py file</li> <li>stay in the swig syntax of insertions in swig generated .py file</li> <li>%pythoncode is ignored if one wraps library to other languages</li> </ol> <p><strong>Update</strong> In a newer version SWIG abandoned <strong>_swig_property</strong> so just use <strong>property</strong>. It works with old version of swig the same. I've changed the post. </p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload