1

I defined a class in python as following.

class myclass:
    def __init__(self,edate,fdate=""):
        print("Constructors with default arguments...")

    def __init__(self):
        print("Default Constructor")

I created an object for this class,

obj = myclass()

It works fine. And I expected the following object creation will work,

obj1 = myclass("01-Feb-2019")

But It throws an error saying,

Traceback (most recent call last):
  File "class.py", line 9, in <module>
    obj = myclass("01-Feb-2019")
TypeError: __init__() takes 1 positional argument but 2 were given

But If I change the definition of the class as follows,

class myclass:
    def __init__(self):
        print("Default Constructor")
    def __init__(self,edate,fdate=""):
        print("Constructors with default arguments...")

Now obj1 = myclass("01-Feb-2019") works. But obj = myclass() throws the following error,

Traceback (most recent call last):
  File "class.py", line 10, in <module>
    obj = myclass()
TypeError: __init__() missing 1 required positional argument: 'edate'

Could we define a constructor overloading in Python? Could I define a constructor which accepts the empty argument as well as one argument?

2
  • Have you looked at how Python stores an object's methods and properties? This behavior will make sense if you do. Commented Feb 16, 2019 at 11:53
  • Within your class you define two methods with the same name __init__. Whichever is the second is what you end up with and respectively - what arguments are expected or not. Commented Feb 16, 2019 at 12:00

4 Answers 4

1

As others have written, Python does not support multiple constructors *). However you can emulate them easily as follows:

class MyClass:
    def __init__(self, edate=None, fdate=""):
        if edate:
            print("Constructors with default arguments...")
        else:
            print("Default Constructor")

Then you can do

obj1 = MyClass("01-Feb-2019")
=> Constructors with default arguments...
obj2 = MyClass()
=> Default Constructor

*) except if you go for multi-dispatch - making use of Python's powerful inspection features

Note that assigning default values in the method declaration should be done very reluctantly as it may work differently than one thinks coming from another language. The proper way to define default values would be using None and assign default values like this

class MyClass:
    def __init__(self, edate=None, fdate=None):
        if edate:
           fdate = "" if fdate is None else fdate
        ... 
Sign up to request clarification or add additional context in comments.

Comments

0

Unlike Java or C#, you cannot define multiple constructors. However, you can define a default value if one is not passed.

Comments

0

Python doesn't have multiple constructors - see Multiple constructors in python?

Comments

0

Use multipledispatch(link) module to overload methods

Installation:

python3 -m pip install multipledispatch

A Dispatcher object stores and selects between different implementations of the same abstract operation. It selects the appropriate implementation based on a signature, or list of types. We build one dispatcher per abstract operation.

The dispatch decorator hides the creation and manipulation of Dispatcher objects from the user.

Using @dispatch wrapper to overload methods:

from multipledispatch import dispatch


class Shape:
    @dispatch(int)
    def __init__(self, length):
        self.length = length
        self.dimension = 1

    @dispatch(float)
    def __init__(self, length):
        self.length = length
        self.dimension = 1

    @dispatch(int, int)
    def __init__(self, length, width):
        self.length = length
        self.width = width
        self.dimension = 2
        self._getArea = lambda: self.length * self.width

    @dispatch(float, float)
    def __init__(self, length, width):
        self.length = length
        self.width = width
        self.dimension = 2
        self._getArea = lambda: self.length * self.width

    @dispatch(int, int, int)
    def __init__(self, length, width, height):
        self.length = length
        self.width = width
        self.height = height
        self.dimension = 3
        self._getArea = lambda: 2 * (self.length * self.width + self.length * self.height +
                                     self.width * self.height)
        self._getVolume = lambda: self.length * self.width * self.height

    @dispatch(float, float, float)
    def __init__(self, length, width, height):
        self.length = length
        self.width = width
        self.height = height
        self.dimension = 3
        self._getArea = lambda: 2 * (self.length * self.width + self.length * self.height +
                                     self.width * self.height)
        self._getVolume = lambda: self.length * self.width * self.height

    def getLength(self):
        return self.length

    def getArea(self):
        if self.dimension == 1:
            raise Exception(f"Shapes with {self.dimension} dimensions have no area")
        return self._getArea()

    def getVolume(self):
        if self.dimension < 3:
            raise Exception(f"Shapes with {self.dimension} dimensions have no volume")
        return self._getVolume()


if __name__ == "__main__":
    line = Shape(3)
    curve = Shape(5.5)
    rectangle = Shape(5.5, 100.1)
    cuboid = Shape(23, 22, 10)

    print(line.getLength())
    print(curve.getLength())
    print(rectangle.getArea())
    print(cuboid.getVolume(), cuboid.getArea())
    
    #will raise Exception since rectangles don't have volume
    print(rectangle.getVolume())

Output:

3
5.5
550.55
5060 1912
Traceback (most recent call last):
....
  Exception: Shapes with 2 dimensions have no volume

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.