Like overloading __init__(), but how?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • John M. Gabriele

    #1

    Like overloading __init__(), but how?

    I know that Python doesn't do method overloading like
    C++ and Java do, but how am I supposed to do something
    like this:

    --------------------- incorrect ------------------------
    #!/usr/bin/python

    class Point3d:
    pass

    class Vector3d:
    """A vector in three-dimensional cartesian space."""

    def __init__( self ):
    """Create a Vector3d with some reasonable default value."""
    x, y, z = 0.0, 0.0, 0.0


    def __init__( self, x_from, y_from, z_from,
    x_to, y_to, z_to ):
    """Create a Vector3d from x-y-z coords."""
    # ...
    pass


    def __init__( self, point_from, point_to ):
    """Create a Vector3d from two Point3d objects."""
    # ...
    pass


    def __init__( self, same_as_this_ve c ):
    """Create a Vector3d from a copy of another one."""
    # ...
    pass

    p = Point3d()
    p2 = Point3d()
    # v = Vector3d( p2, p ) -- Nope. Only the last __init__() counts.

    ---------------------- /incorrect -------------------------------

    Thanks.

    --
    --- if replying via email, remove zees ---


  • Steven Bethard

    #2
    Re: Like overloading __init__(), but how?

    John M. Gabriele wrote:[color=blue]
    > 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_ve c):
    > ...[/color]

    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_fr om=..., 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('expe cted 0, 1, 2 or 6 args, got %i' %
    len(args))

    But this can get really ugly really quick.

    HTH,

    STeVe

    Comment

    • djw

      #3
      Re: Like overloading __init__(), but how?

      This was discussed only days ago:



      -Don


      John M. Gabriele wrote:[color=blue]
      > I know that Python doesn't do method overloading like
      > C++ and Java do, but how am I supposed to do something
      > like this:
      >
      > --------------------- incorrect ------------------------
      > #!/usr/bin/python
      >
      > class Point3d:
      > pass
      >
      > class Vector3d:
      > """A vector in three-dimensional cartesian space."""
      >
      > def __init__( self ):
      > """Create a Vector3d with some reasonable default value."""
      > x, y, z = 0.0, 0.0, 0.0
      >
      >
      > def __init__( self, x_from, y_from, z_from,
      > x_to, y_to, z_to ):
      > """Create a Vector3d from x-y-z coords."""
      > # ...
      > pass
      >
      >
      > def __init__( self, point_from, point_to ):
      > """Create a Vector3d from two Point3d objects."""
      > # ...
      > pass
      >
      >
      > def __init__( self, same_as_this_ve c ):
      > """Create a Vector3d from a copy of another one."""
      > # ...
      > pass
      >
      > p = Point3d()
      > p2 = Point3d()
      > # v = Vector3d( p2, p ) -- Nope. Only the last __init__() counts.
      >
      > ---------------------- /incorrect -------------------------------
      >
      > Thanks.
      >[/color]

      Comment

      • Kent Johnson

        #4
        Re: Like overloading __init__(), but how?

        John M. Gabriele wrote:[color=blue]
        > I know that Python doesn't do method overloading like
        > C++ and Java do, but how am I supposed to do something
        > like this:[/color]

        This was just discussed. See
        http://tinyurl.com/6zo3g

        Kent
        [color=blue]
        >
        > --------------------- incorrect ------------------------
        > #!/usr/bin/python
        >
        > class Point3d:
        > pass
        >
        > class Vector3d:
        > """A vector in three-dimensional cartesian space."""
        >
        > def __init__( self ):
        > """Create a Vector3d with some reasonable default value."""
        > x, y, z = 0.0, 0.0, 0.0
        >
        >
        > def __init__( self, x_from, y_from, z_from,
        > x_to, y_to, z_to ):
        > """Create a Vector3d from x-y-z coords."""
        > # ...
        > pass
        >
        >
        > def __init__( self, point_from, point_to ):
        > """Create a Vector3d from two Point3d objects."""
        > # ...
        > pass
        >
        >
        > def __init__( self, same_as_this_ve c ):
        > """Create a Vector3d from a copy of another one."""
        > # ...
        > pass
        >
        > p = Point3d()
        > p2 = Point3d()
        > # v = Vector3d( p2, p ) -- Nope. Only the last __init__() counts.
        >
        > ---------------------- /incorrect -------------------------------
        >
        > Thanks.
        >[/color]

        Comment

        • John M. Gabriele

          #5
          Re: Like overloading __init__(), but how?

          On Wed, 23 Feb 2005 21:32:52 -0700, Steven Bethard wrote:
          [color=blue]
          > [snip]
          > 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('expe cted 0, 1, 2 or 6 args, got %i' %
          > len(args))
          >
          > But this can get really ugly really quick.
          >
          > HTH,
          >
          > STeVe[/color]

          Thanks STeVe. I think, for now, I'll probably stick with
          the easier but less elegant way of checking *args. I guess
          I could compare args[0].__class__.__na me__ against 'Point3d',
          'Vector3d', or just 'float'.

          Didn't realize this topic came up recently. Sorry for the
          duplication.

          ---J

          --
          --- if replying via email, remove zees ---


          Comment

          Working...