constructor and method overriding in Python
Question: I am trying to figure out if there is a way to override the `__init__` method
in a python class. I have come up with this, not exactly method overriding but
it has the same effect

    
    
    class A():
        def __init__(self, x):
            if isinstance(x, str):
                print "calling some text parsing method"
            elif isinstance(x, int):
                print "calling some number crunching method"
            else:
                print "Oops"
    

Is this good practice please? Not only for constructors as in this particular
question but also for other methods too


Answer: That's essentially what you need to do, if the actions for a string argument
are very different from the actions for an integer argument. However, if one
case reduces to the other, then you can define a class method as an alternate
constructor. As an simple example, consider

    
    
    class A():
        def __init__(self, x):
            if isinstance(x, str):
                self.x = int(x)
            elif isinstance(x, int):
                self.x = x
            else:
                raise ValueError("Cannot turn %s into an int" % (x, ))
    

Here, the integer case is the "fundamental" way to create an instance of `A`;
the string case reduces to turning the string into an integer, then proceding
as in the integer case. You might rewrite this as

    
    
    class A():
        # x is expected to be an integer
        def __init__(self, x):
            self.x = x
    
        # x is expected to be a string
        @classmethod
        def from_string(cls, x):
            try:
                return cls(int(x))
            except ValueError:
                # This doesn't really do anything except reword the exception; just an example
                raise ValueError("Cannot turn %s into an int" % (x, ))
    

In general, you want to avoid checking for the type of a value, because types
are less important than behavior. For example, `from_string` above doesn't
really expect a string; it just expects something that can be turned into an
`int`. That could be a `str` or a `float`.

