Like overloading __init__(), but how?

Steven Bethard steven.bethard at gmail.com
Wed Feb 23 23:32:52 EST 2005


John M. Gabriele wrote:
> class Vector3d:
>       def __init__(self):
>             ...
>       def __init__(self, x_from, y_from, z_from, x_to, y_to, z_to):
>             ...
>       def __init__(self, point_from, point_to):
>             ...
>       def __init__(self, same_as_this_vec):
>             ...

My preferred option is to break these into different methods.  I pick 
the xyz-coords (and the empty coords) __init__ as the most basic cases, 
but if you find one of the other cases to be more basic, the 
modification should be pretty simple.

class Vector3d(object):
     # define init to take only xyz coords (missing coords default to 0)
     # this covers your first two cases, I think
     def __init__(self, x_from=0.0, y_from=0.0, z_from=0.0,
                        x_to=0.0,   y_to=0.0,   z_to=0.0):
         ...

     # define a classmethod that creates a Vector3d from points
     # this covers your third case
     @classmethod
     def from_points(cls, point_from, point_to):
         ...
         return cls(x_from=..., y_from=..., ...)

     # define copy as an instance method, not a constructor
     # this covers your fourth case
     def copy(self):
         ...
         return type(self)(x_from=..., y_from=..., ...)


Another possibility is to play around with *args:

class Vector3d(object):
     def __init__(self, *args):
         if not args:
             # constructor with no arguments
         elif len(args) == 6:
             # constructor with xyz coords
         elif len(args) == 2:
             # constructor with points
         elif len(args) == 1:
             # copy constructor
         else:
             raise TypeError('expected 0, 1, 2 or 6 args, got %i' %
                             len(args))

But this can get really ugly really quick.

HTH,

STeVe



More information about the Python-list mailing list