FAQ
Hello NG,

I am trying to port a useful class from wxWidgets (C++) to a pure Python/wxPython
implementation. In the C++ source code, a unique class is initialized with
2 different methods (???). This is what it seems to me. I have this declarations:

class wxFoldWindowItem
{
private:
wxWindow *_wnd;
int _type, _flags;
int _leftSpacing,
_rightSpacing,
_ySpacing;
int _lineWidth, _lineY;
wxColour _sepLineColour;

public:
enum
{
WINDOW = 0,
SEPARATOR
};

// wxWindow constructor. This initialises the class as a wxWindow type
wxFoldWindowItem(wxWindow *wnd, int flags = wxFPB_ALIGN_WIDTH, int ySpacing
= wxFPB_DEFAULT_YSPACING,
int leftSpacing = wxFPB_DEFAULT_LEFTSPACING, int rightSpacing
= wxFPB_DEFAULT_RIGHTSPACING)
: _wnd(wnd)
, _type(WINDOW)
, _flags(flags)
, _leftSpacing(leftSpacing)
, _rightSpacing(rightSpacing)
, _ySpacing(ySpacing)
, _lineWidth(0)
, _lineY(0)
{
};

// separator constructor. This initialises the class as a separator
type
wxFoldWindowItem(int y, const wxColour &lineColor = *wxBLACK, int ySpacing
= wxFPB_DEFAULT_YSPACING,
int leftSpacing = wxFPB_DEFAULT_LEFTLINESPACING,
int rightSpacing = wxFPB_DEFAULT_RIGHTLINESPACING)

: _wnd(0)
, _type(SEPARATOR)
, _flags(wxFPB_ALIGN_WIDTH)
, _leftSpacing(leftSpacing)
, _rightSpacing(rightSpacing)
, _ySpacing(ySpacing)
, _lineWidth(0)
, _lineY(y)
, _sepLineColour(lineColor)
{
};

The 2 different initializations refers to completely different objects (the
first one is a wx.Window, the second one is an horizontal line). Next, there
are a lot of functions that, depending on the variable _type, return properties
of the wx.Window or of the line. I would like to keep the same names for
classes/methods, so it would be useful to have the same class with 2 different
"initializations".
Does anyone know if is there a way to achieve the same thing in Python/wxPython?
Someone else has talked about overloaded constructors, but I don't have
any idea on how to implement this kind of "constructors" in Python. Does
anyone have a small example of overloaded constructors in Python?
I have no idea... Or am I missing something obvious?

Thanks to you all.

Andrea.

Search Discussions

  • Kent Johnson at Mar 20, 2005 at 10:13 pm

    andrea_gavana at tin.it wrote:
    Hello NG,

    I am trying to port a useful class from wxWidgets (C++) to a pure Python/wxPython
    implementation. In the C++ source code, a unique class is initialized with
    2 different methods (???). This is what it seems to me. I have this declarations:

    class wxFoldWindowItem
    {
    // wxWindow constructor. This initialises the class as a wxWindow type
    wxFoldWindowItem(wxWindow *wnd, int flags = wxFPB_ALIGN_WIDTH, int ySpacing
    = wxFPB_DEFAULT_YSPACING,
    int leftSpacing = wxFPB_DEFAULT_LEFTSPACING, int rightSpacing
    = wxFPB_DEFAULT_RIGHTSPACING)
    : _wnd(wnd)
    , _type(WINDOW)
    , _flags(flags)
    , _leftSpacing(leftSpacing)
    , _rightSpacing(rightSpacing)
    , _ySpacing(ySpacing)
    , _lineWidth(0)
    , _lineY(0)
    {
    };

    // separator constructor. This initialises the class as a separator
    type
    wxFoldWindowItem(int y, const wxColour &lineColor = *wxBLACK, int ySpacing
    = wxFPB_DEFAULT_YSPACING,
    int leftSpacing = wxFPB_DEFAULT_LEFTLINESPACING,
    int rightSpacing = wxFPB_DEFAULT_RIGHTLINESPACING)

    : _wnd(0)
    , _type(SEPARATOR)
    , _flags(wxFPB_ALIGN_WIDTH)
    , _leftSpacing(leftSpacing)
    , _rightSpacing(rightSpacing)
    , _ySpacing(ySpacing)
    , _lineWidth(0)
    , _lineY(y)
    , _sepLineColour(lineColor)
    {
    };

    The 2 different initializations refers to completely different objects (the
    first one is a wx.Window, the second one is an horizontal line).
    This is a strange design. My first reaction is, why do you want to do that? Maybe you should split
    the class in two?

    Next, there
    are a lot of functions that, depending on the variable _type, return properties
    of the wx.Window or of the line. I would like to keep the same names for
    classes/methods, so it would be useful to have the same class with 2 different
    "initializations".
    One way to do this in Python is to have a single constructor that looks at the type / number of
    arguments to figure out what it is supposed to do. Another way is to make two factory methods that
    create instances of the class and do the correct initialization.

    Kent
  • Andrea_gavana at Mar 20, 2005 at 10:29 pm
    Hello Kent,

    thank you a lot for your answer. I was starting to think that my question
    was a little bit strange to obtain an answer...
    This is a strange design. My first reaction is, why do you want to do that?
    Maybe you >should split the class in two?

    You are right. The problem is that this is not my code. Someone else has
    written it and, since it is a useful widget to have in a wxPython GUI, I
    was trying to port it to Python. I don't want to mess with things like SWIG,
    because this widget (compiled in C++) is not portable through all platforms,
    while pure Python code should be.
    I could split the class in two, but I would like to keep the class/functions
    definitions as closer as possible to the original one.
    Next, there
    are a lot of functions that, depending on the variable _type, return
    properties
    of the wx.Window or of the line. I would like to keep the same names
    for
    classes/methods, so it would be useful to have the same class with 2
    different
    "initializations".
    One way to do this in Python is to have a single constructor that looks
    at the type / >number of arguments to figure out what it is supposed to
    do.

    I am trying to figure it out using something like:

    def __init__(self, parent, **kw):

    and processing the keyword args, but it does not satisfy me very much...
    Another way is to make two factory methods that
    create instances of the class and do the correct initialization.
    I am sorry to be so tedious, but I am still quite a newbie in Python...
    could you please provide a very small example of your last sentence? Looks
    quite interesting...

    Thank you a lot.

    Andrea.
  • Michael Spencer at Mar 20, 2005 at 11:27 pm

    andrea_gavana at tin.it wrote:
    [trying to create a single Python class with the equivalent of the following overloaded constructors]

    wxFoldWindowItem(wxWindow *wnd, int flags = wxFPB_ALIGN_WIDTH,
    int ySpacing = wxFPB_DEFAULT_YSPACING,
    int leftSpacing = wxFPB_DEFAULT_LEFTSPACING,
    int rightSpacing = wxFPB_DEFAULT_RIGHTSPACING)

    or

    wxFoldWindowItem(int y, const wxColour &lineColor = *wxBLACK,
    int ySpacing = wxFPB_DEFAULT_YSPACING,
    int leftSpacing = wxFPB_DEFAULT_LEFTLINESPACING,
    int rightSpacing = wxFPB_DEFAULT_RIGHTLINESPACING)

    Several options in addition to the factory function that Kent has suggested (and
    I'll assume he'll follow up with clarification)

    # Option 1: one abstract base class holding all/most of the methods, and two
    separate subclasses reflecting the two use-cases.

    class _AbstractFoldWindowItem(object):
    def __init__(self, *args, **kw):
    raise NotImplemetedError

    def
    ... all the shared methods

    then

    class FoldWindowItem(_AbstractFoldWindowItem):
    def __init__(self, wxWindow, flags = wxFPB_ALIGN_WIDTH,
    ySpacing = wxFPB_DEFAULT_YSPACING,
    leftSpacing = wxFPB_DEFAULT_LEFTSPACING,
    rightSpacing = wxFPB_DEFAULT_RIGHTSPACING):

    class FoldSeparator(_AbstractFoldWindowItem):
    def __init__(self, y, lineColor = wx.BLACK,
    ySpacing = wx.FPB_DEFAULT_YSPACING,
    leftSpacing = wx.FPB_DEFAULT_LEFTLINESPACING,
    rightSpacing = wx.FPB_DEFAULT_RIGHTLINESPACING):


    # Option 2: One class, two constructors:

    class FoldWindowItem():

    def __init__(self, wxWindow, flags = wxFPB_ALIGN_WIDTH,
    ySpacing = wxFPB_DEFAULT_YSPACING,
    leftSpacing = wxFPB_DEFAULT_LEFTSPACING,
    rightSpacing = wxFPB_DEFAULT_RIGHTSPACING):
    """Initializes with wxWindow"""
    self._type = wx.Window

    @classmethod
    def FromSeparator(cls, y, lineColor = wx.BLACK,
    ySpacing = wx.FPB_DEFAULT_YSPACING,
    leftSpacing = wx.FPB_DEFAULT_LEFTLINESPACING,
    rightSpacing = wx.FPB_DEFAULT_RIGHTLINESPACING):
    newobj = cls.__new__(y, lineColor = wx.BLACK,
    ySpacing = wx.FPB_DEFAULT_YSPACING,
    leftSpacing = wx.FPB_DEFAULT_LEFTLINESPACING,
    rightSpacing = wx.FPB_DEFAULT_RIGHTLINESPACING)
    newobj._type = wx.SEPARATOR
    # other initializatio
    return newobj

    This requires the user code to call the class in two ways depending on how it is
    to be used:

    i.e., myFoldWindowItem = FoldWindowItem(Window)
    or myFoldWindowItem = FoldWindowItem.FromSeparator(y)



    # Option 3: inspect the arguments and provide the signature details in the docstring

    class FoldWindowItem():

    def __init__(self, obj, **kw):
    """Initialize with:
    wxWindow, flags = wxFPB_ALIGN_WIDTH,
    ySpacing = wxFPB_DEFAULT_YSPACING,
    leftSpacing = wxFPB_DEFAULT_LEFTSPACING,
    rightSpacing = wxFPB_DEFAULT_RIGHTSPACING)

    or:
    y, lineColor = wx.BLACK,
    ySpacing = wx.FPB_DEFAULT_YSPACING,
    leftSpacing = wx.FPB_DEFAULT_LEFTLINESPACING,
    rightSpacing = wx.FPB_DEFAULT_RIGHTLINESPACING)"""

    if isinstance(obj, wx.Window):
    # Do one thing
    elif isinstance(obj, wx.SEPARATOR):
    # Do the other


    HTH

    Michael
  • Shalabh Chaturvedi at Mar 20, 2005 at 11:49 pm

    andrea_gavana at tin.it wrote:
    Hello NG,

    I am trying to port a useful class from wxWidgets (C++) to a pure Python/wxPython
    implementation. In the C++ source code, a unique class is initialized with
    2 different methods (???). This is what it seems to me. I have this declarations:
    <C++ code snipped>
    The 2 different initializations refers to completely different objects (the
    first one is a wx.Window, the second one is an horizontal line).
    Does anyone know if is there a way to achieve the same thing in Python/wxPython?
    Someone else has talked about overloaded constructors, but I don't have
    any idea on how to implement this kind of "constructors" in Python. Does
    anyone have a small example of overloaded constructors in Python?
    I have no idea... Or am I missing something obvious?
    If you do have to do something like this you could use keyword arguments
    with defaults. For example:

    class C(object):
    def __init__(self, a=None, b=None):
    if None not in (a, b):
    raise some error (only one of a/b should be given)

    if a:
    # do something
    elif b:
    # do something else


    Another way to do it is to use classmethods:

    class C(object):

    def __init__(self):
    # do initialization

    def create_one(cls, a):
    obj = cls()
    # do something with a
    return obj

    create_one = classmethod(create_one)

    def create_two(cls, b):
    obj = cls()
    # do something with b
    return obj

    create_two = classmethod(create_two)

    Then you can use it thus:

    x = C.create_one(a='value')

    y = C.create_two(b='value')

    Because it is a classmethod, calling C.create_one('value') calls
    create_one() with two parameters:
    - C
    - 'value'

    i.e. the first parameter is the class, not an instance of the class.

    Hope this helped.

    Shalabh
  • Paul McGuire at Mar 21, 2005 at 2:49 am

    Another way is to make two factory methods that
    create instances of the class and do the correct initialization.
    I am sorry to be so tedious, but I am still quite a
    newbie in Python... could you please provide a very
    small example of your last sentence? Looks
    quite interesting...
    See the recipe at this link. It defines a basic constructor to create
    Color objects using 3 integer args for red/green/blue, and a separate
    staticmethod as a factory method to create a Color using a single
    integer representing an RBG value.

    http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/223611

    -- Paul
    (This recipe was taken from a much larger sample for basic bitmap
    drawing, which you will find at
    http://www.geocities.com/ptmcg/python/index.html#bmp .)

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
grouppython-list @
categoriespython
postedMar 20, '05 at 1:10p
activeMar 21, '05 at 2:49a
posts6
users5
websitepython.org

People

Translate

site design / logo © 2021 Grokbase