FAQ
Hallo everybody,

is it possible to implement multiple constructors with different no. of arguments for one class ?
class A:
def __init__(self, a):
self._a = a
def __init__(self,a,b):
self._b = b
def __init__(self,a,b,c):
self._c =c
obj = A(12)
Traceback (most recent call last):
File "<pyshell#2>", line 1, in ?
obj = A(12)
TypeError: __init__() takes exactly 4 arguments (2 given)
>>>

--------------------------------
That doesn't work. Any suggestions ?

Thanks in forward

Alexander

Search Discussions

  • Sismex01 at Oct 14, 2002 at 4:44 pm

    From: Alexander Eisenhuth [mailto:stacom at stacom-software.de]

    Hallo everybody,

    is it possible to implement multiple constructors with
    different no. of arguments for one class ?
    class A:
    def __init__(self, a):
    self._a = a
    def __init__(self,a,b):
    self._b = b
    def __init__(self,a,b,c):
    self._c =c
    Urgh... this is, like, *so* C++-ish.

    ;-)
    obj = A(12)
    Traceback (most recent call last):
    File "<pyshell#2>", line 1, in ?
    obj = A(12)
    TypeError: __init__() takes exactly 4 arguments (2 given)
    I'm probly gonna get lambasted by C++ peepl, but what'the'h.
    C++ *supposedly* has multiple function dispatch, depending on
    the function's signature. The compiler matches the number and
    type of arguments to the function, and magically calls the
    apropriate one.

    Alas, it is but a fiendish LIE!

    C++ mangles all code object names depending on their signature,
    turning them into intellegibly hideous caricatures of their
    logical, pronouncable, thinkable, former selves; all in the
    name of pseudo-multimethod-dispatch.

    OTOH, Python doesn't do this supposed pseudo-multimethod-dispatch,
    so you have to roll your own. BUT, there's no artificial
    restrictions on the types and number or arguments you might
    receive, so you can do your own stuff depending on optional
    parameters you might define.

    So, suppose you have this class:

    class MagicalQueue:
    def __init__(self, min, max, init):
    self._min = min
    self._max = max
    self._data = []
    self._data += init # (because it's supposed to be a list)

    and you want the extra constructors depending on the number
    and type of arguments, right?

    Well, for one, min isn't ever going to be less than zero,
    so you can make that argument optional. Max is (probably)
    an optional argument also, depending if you want your queue
    bounded or not; and initial data is most certainly an optional
    argument also.

    So, the constructor can be redefined as:

    def __init__(self, min=0, max=None, init=None):
    self._min = min
    self._max = max
    self._data = []
    if init:
    self._data += init

    So now, functionally, it's like using multiple initializers,
    but actually it's the same making some intelligent decisions
    inside.

    Cool, eh?

    :-)

    In other words, you have to design your software *around* this
    supposed limitation, which isn't really a limitation; I consider
    C++ with all the hoops and loops one has to use much more
    limiting.

    HTH

    -gustavo
  • Alan Kennedy at Oct 14, 2002 at 4:49 pm

    Alexander Eisenhuth wrote:
    is it possible to implement multiple constructors with different no.
    of arguments for one class ?
    In a word, no.

    Instead, you have to use python's default argument capabilities, and a
    single constructor, like so

    class A:

    def __init__(self, a, b="default", c="default")
    self.a = a
    self.b = b
    self.c = c
    o1 = A("str")
    o1.a, o1.b, o1.c
    ("str", "default", "default")
    o2 = A("str", "notdefault")
    o2.a, o2.b, o2.c
    ("str", "notdefault", "default")
    o3 = A("str", "notdefault", "notdef")
    o3.a, o3.b, o3.c
    ("str", "notdefault", "notdef")

    HTH,

    alan kennedy
    -----------------------------------------------------
    check http headers here: http://xhaus.com/headers
    email alan: http://xhaus.com/mailto/alan
  • Lexy Zhitenev at Oct 14, 2002 at 5:00 pm
    Actually, there is one more way to do it.

    class A:
    def __init__(self, *args):
    if len(args) == 1: __init__0(self, *args)
    elif len(args) == 2: __init__1(self, *args)
    elif len(args) == 3: __init__2(self, *args)
    def __init__0(self):
    pass
    def __init__1(self, a):
    pass
    def __init__2(self, a, b):
    pass
    def __init__3(self, a, b, c)

    Or something like that. Certainly, this code can be a bit optimized, but
    roughly it is so.
  • Sean 'Shaleh' Perry at Oct 14, 2002 at 5:22 pm

    On Monday 14 October 2002 10:00, Lexy Zhitenev wrote:
    Actually, there is one more way to do it.

    class A:
    def __init__(self, *args):
    if len(args) == 1: __init__0(self, *args)
    elif len(args) == 2: __init__1(self, *args)
    elif len(args) == 3: __init__2(self, *args)
    def __init__0(self):
    pass
    def __init__1(self, a):
    pass
    def __init__2(self, a, b):
    pass
    def __init__3(self, a, b, c)

    Or something like that. Certainly, this code can be a bit optimized, but
    roughly it is so.
    another solution is to use the *args definition and then do:

    if type(args[0]) == type(0):
    # handle number input
    elif type(args[0] == type(""):
    # handle string input

    etc.
  • Anton Vredegoor at Oct 14, 2002 at 5:08 pm

    On Mon, 14 Oct 2002 18:31:04 +0200, Alexander Eisenhuth wrote:

    is it possible to implement multiple constructors with different no. of arguments for one class ?
    class A:
    def __init__(self, a):
    self._a = a
    def __init__(self,a,b):
    self._b = b
    def __init__(self,a,b,c):
    self._c =c
    obj = A(12)
    Traceback (most recent call last):
    File "<pyshell#2>", line 1, in ?
    obj = A(12)
    TypeError: __init__() takes exactly 4 arguments (2 given)
    --------------------------------
    That doesn't work. Any suggestions ?
    Only the last __init__ is preserved, because the previous definitions
    are overridden by the last one.

    A possible solution is to use default values:
    def __init__(self, a = None, b = None, c = None):
    Now if an argument is not provided it is set to None, the "default"
    value. This works if one or more arguments are provided in their
    respective order. To provide only a specific argument, use a keyword:

    obj = A(b)

    Note that the first argument "self" which stands for the object itself
    is counted as an argument but is filled in automagically.

    Anton.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
grouppython-list @
categoriespython
postedOct 14, '02 at 4:31p
activeOct 14, '02 at 5:22p
posts6
users6
websitepython.org

People

Translate

site design / logo © 2022 Grokbase