Search code examples
pythonclassoopconstructor-overloading

Point of overloaded constructor in Python?


I am having trouble understanding exactly what this piece of code is useful for

class buildArgs:
    def __init__(self, host, port, user, dept):
        self._dept = dept
        self._host = host
        self._port = port
        self._user = user
        self._datacenter = datacenter
        self._path = path
    def __init__(self): 
        self._dept = None
        self._host = None
        self._port = None
        self._user = None
        self._datacenter = None
        self._path = None

This is then followed by a bunch of @property methods followed by setters like so and then the main method:

@property
def port(self):
    return self._port
@port.setter
def port(self, port):
    self._port = port

I've never seen two __init__ functions under a class in Python before and am assuming this is unpythonic. What is the correct approach for this type of logic?


Solution

  • What that code does is equivalent to not defining the first __init__ at all (it just gets replaced by the second immediately, and it is never seen again).

    You could get something similar to both behaviors by only using the first constructor, and giving all parameters a default of None:

    def __init__(self, host=None, port=None, user=None, dept=None):
            self._dept = dept
            self._host = host
            self._port = port
            self._user = user
    

    which would also allow for providing some arguments, but not all. For more complicated cases, define an alternate constructor as a @classmethod (class methods exist primarily to implement alternate constructors), where it converts (or provides) its own arguments to the ones expected by the primary constructor, then ends with return cls(expected, arguments, here):

    class buildArgs:
        def __init__(self, host, port, user, dept):
            self._dept = dept
            self._host = host
            self._port = port
            self._user = user
    
        @classmethod
        def from_the_void(cls):
            return cls(None, None, None, None)