In addition to working with Python, I also work with Java quite a lot.
When coding in Python, I occasionally encounter situations in which I wish I could code multiple constructors (with different signatures) for a class, the way you can in Java.
Recently, someone else had the same desire, and posted his question on comp.lang.python. So I thought that I would post an example of the technique that I use, in case others might find it useful. So here it is:
==========================================
import sys, types, pprint class Vector: """ Demo of a class with multiple signatures for the constructor """ def __init__(self, *args, **kwargs): if len(args) == 1: foundOneArg = True; theOnlyArg = args[0] else: foundOneArg = False; theOnlyArg = None if foundOneArg and isinstance(theOnlyArg, types.ListType): self.initializeFromList(theOnlyArg) elif foundOneArg and isinstance(theOnlyArg,Vector): self.initializeFromVector(theOnlyArg) else: self.initializeFromArgs(*args) pprint.pprint(self.values) # for debugging only def initializeFromList(self, argList): self.values = [x for x in argList] def initializeFromVector(self, vector): self.values = [x for x in vector.values] def initializeFromArgs(self, *args): self.values = [x for x in args] #------------ end of class definition --------------------- v = Vector(1,2,3) v = Vector([4,5,6]) q = Vector(v);
I’d almost be inclined to make an automated procedure for doing the arg checking, and use a decorator to declare individual methods as constructors.
I don’t have the code on me at the moment, so you’ll have to leave it at that for the moment.
I personally never was a fan of such a design- specifically relying on *args/**kwargs means in looking at the prototype you’ve nfc what args it actually takes, forcing you to access the doc string for it (instead of just doing a quick inspection of it).
What I do instead, and I think is cleaner/simpler is to invert what you’ve got there- instead of __init__ trying to figure out which internal initialization to invoke, I use classmethods to translate the various init signatures into the common __init__ signature.
Benefits of this is 1) explicit intentions, 2) simpler internal init, 3) usable method signatures, 4) easier to subclass/override (think of if you needed to change the prototype signature for one of the subinits- your current code, __init__ would have to basically be reimplemented in the derivative).
Also reads a fair bit better in invoking code in my experience.
This example is a little trivial, so it’s hard to really demonstrate good examples. But usually I use a classmethod for alternate constructors. For example: http://gist.github.com/335850
Otherwise I sometimes use keyword arguments, which are explicit about what kind of thing is being passed in. Doing full type inspection of constructor arguments is hard (or it is sloppy).
I’ll just echo what Ian said: I tend to use classmethods with names like “from_list”, “from_vector” whose responsibility it is to invoke __init__ in a sensible manner.
Here’s my stab at a prettier version:
A mutable object in a definition… really? return iter(self.values) in __iter__ would also be a better solution.