Why doesn't python support multiple constructors like Java?

Question:

I know python isn’t Java—and I’m not trying to be biased towards Java or something. I barely even use Java. I know you can set a default value of a init parameter in python by doing something like:

def __init__(name = "Quinn"):
    self.name = name

but what if you wanted to do something for an Item class in a game like:

def __init__(someComplexDict):
    self.name = someComplexDict ["name"]
    self.description = someComplexDict ["description"]
    etc. etc. etc...

Yeah, sure, you could try and set the someComplexDict parameter with a lot of keys to a default value, but then it would look like this:

def __init__(someComplexDict = {"name": "default", "description": "default description":, "item price": 0, "item rarity": "default", and even more keys}):
    # and then just define all the self variables here

And what if you wanted to have even more parameters? It looks so messy to me. If I remember correctly, in Java, you can have multiple constructors so that you could structure it like (i’m just going to use python syntax for the Java multiple constructors concept):

def __init__():
    self.name = "default"
    self.description= "default description"
    self.itemPrice = 0,
    self.itemRarity = "default"
    blah blah blah

def __init__(dict):
    self.name = dict["name"]
    self.description = dict["description"]
    self.itemPrice = dict["item price"]
    self.itemRarity = dict["item rarity"]
    blah blah blah

In my opinion, multiple constructors make the init parameters not look like a monstrosity. Am I wrong about this? I’m new to python so I could be totally mistaken. I see people say that concepts in other languages aren’t "pythonic" and don’t fit the purpose of python being simple, but I really don’t see how multiple constructors could be non-pythonic, it seems pretty simple to me.

Asked By: QuinnMcChief

||

Answers:

The general pattern in Python to give an argument a default dict value is to give it a default value of None first, and then assign to it a dict value if it is found to be None:

def __init__(self, someComplexDict=None):
    if someComplexDict is None:
        someComplexDict = {"name": "default", "description": "default description"}
    self.name = someComplexDict["name"]
    self.description = someComplexDict["description"]

This pattern also minimizes code duplication seen in the sample code in your question where assignments to individual attributes are duplicated.

If you do want multiple constructors in Python, the general practice is to create additional class methods as alternative constructors:

class Foo:
    def __init__(self, name="default", description="description"):
        self.name = name
        self.description = description

    @classmethod
    def from_dict(cls, someComplexDict=None):
        if someComplexDict is None:
            someComplexDict = {"name": "default from dict", "description": "default description from dict"}
        obj = cls.__new__(cls)
        obj.name = someComplexDict["name"]
        obj.description = someComplexDict["description"]
        return obj

foo = Foo()
print(foo.name)
print(foo.description)
foo = Foo.from_dict()
print(foo.name)
print(foo.description)

This outputs:

default
description
default from dict
default description from dict
Answered By: blhsing
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.