Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it not possible to define multiple constructors in Python? [duplicate]

People also ask

Can you define multiple constructors in Python?

Providing Multiple Constructors With @classmethod in Python. A powerful technique for providing multiple constructors in Python is to use @classmethod . This decorator allows you to turn a regular method into a class method. Unlike regular methods, class methods don't take the current instance, self , as an argument.

Can you have multiple constructors with the same name?

A user can implement constructor overloading by defining two or more constructors in a class sharing the same name.

Can we use multiple constructors in same class?

There can be multiple constructors in a class. However, the parameter list of the constructors should not be same. This is known as constructor overloading.

Can there be multiple constructors?

The technique of having two (or more) constructors in a class is known as constructor overloading. A class can have multiple constructors that differ in the number and/or type of their parameters. It's not, however, possible to have two constructors with the exact same parameters.


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

def __init__(self, city="Berlin"):
  self.city = city

If your signatures differ only in the number of arguments, using default arguments is the right way to do it. If you want to be able to pass in different kinds of argument, I would try to avoid the isinstance-based approach mentioned in another answer, and instead use keyword arguments.

If using just keyword arguments becomes unwieldy, you can combine it with classmethods (the bzrlib code likes this approach). This is just a silly example, but I hope you get the idea:

class C(object):

    def __init__(self, fd):
        # Assume fd is a file-like object.
        self.fd = fd

    @classmethod
    def fromfilename(cls, name):
        return cls(open(name, 'rb'))

# Now you can do:
c = C(fd)
# or:
c = C.fromfilename('a filename')

Notice all those classmethods still go through the same __init__, but using classmethods can be much more convenient than having to remember what combinations of keyword arguments to __init__ work.

isinstance is best avoided because Python's duck typing makes it hard to figure out what kind of object was actually passed in. For example: if you want to take either a filename or a file-like object you cannot use isinstance(arg, file), because there are many file-like objects that do not subclass file (like the ones returned from urllib, or StringIO, or...). It's usually a better idea to just have the caller tell you explicitly what kind of object was meant, by using different keyword arguments.


For the example you gave, use default values:

class City:
    def __init__(self, name="Default City Name"):
        ...
    ...

In general, you have two options:

1) Do if-elif blocks based on the type:

def __init__(self, name):
    if isinstance(name, str):
        ...
    elif isinstance(name, City):
        ...
    ...

2) Use duck typing --- that is, assume the user of your class is intelligent enough to use it correctly. This is typically the preferred option.


The easiest way is through keyword arguments:

class City():
  def __init__(self, city=None):
    pass

someCity = City(city="Berlin")

This is pretty basic stuff. Maybe look at the Python documentation?