Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Constructor overloading

Reply
Thread Tools

Constructor overloading

 
 
Sergey Krushinsky
Guest
Posts: n/a
 
      06-09-2004
Hello all,

Is there a common way to emulate constructor overloading in Python class?

For instanse, I have 3 classes:
1/ Polar - to hold polar coordinates;
2/ Cartesian - to hold cartesian coordinates;
3/ Coordinates3D, which holds synchronized instances of the both in
__p__ and __c__ fields respectively.

I want to design Coordinates3D so that when instantiated with Polar
argument, self.__p__=argument passed to constructor, and self.__c__ is
calculated. When argument is Cartesian, self.__c__=argument, and
self.__p__ is calculated. Runtime type checking works, but maybe there
is a better way?

Thanks in advance,
Sergey

 
Reply With Quote
 
 
 
 
John Roth
Guest
Posts: n/a
 
      06-09-2004
"Sergey Krushinsky" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> Hello all,
>
> Is there a common way to emulate constructor overloading in Python class?
>
> For instanse, I have 3 classes:
> 1/ Polar - to hold polar coordinates;
> 2/ Cartesian - to hold cartesian coordinates;
> 3/ Coordinates3D, which holds synchronized instances of the both in
> __p__ and __c__ fields respectively.
>
> I want to design Coordinates3D so that when instantiated with Polar
> argument, self.__p__=argument passed to constructor, and self.__c__ is
> calculated. When argument is Cartesian, self.__c__=argument, and
> self.__p__ is calculated. Runtime type checking works, but maybe there
> is a better way?


Depends on what you think is "better." Checking the paramter
types at run time is the clearest way of doing it. The only other
way I know is to use a static method as a constructor, instantiate
an instance of object(), change its class and initialize it to suit
yourself.

The biggest problem with that is that it's totally non-obvious
unless your team does it a lot, and you've got decent naming
conventions so you know what's happening.

John Roth
>
> Thanks in advance,
> Sergey
>



 
Reply With Quote
 
 
 
 
Peter Otten
Guest
Posts: n/a
 
      06-09-2004
Sergey Krushinsky wrote:

> Hello all,
>
> Is there a common way to emulate constructor overloading in Python class?
>
> For instanse, I have 3 classes:
> 1/ Polar - to hold polar coordinates;
> 2/ Cartesian - to hold cartesian coordinates;
> 3/ Coordinates3D, which holds synchronized instances of the both in
> __p__ and __c__ fields respectively.
>
> I want to design Coordinates3D so that when instantiated with Polar
> argument, self.__p__=argument passed to constructor, and self.__c__ is
> calculated. When argument is Cartesian, self.__c__=argument, and
> self.__p__ is calculated. Runtime type checking works, but maybe there
> is a better way?
>
> Thanks in advance,
> Sergey


Given that Polar and Cartesian could easily grow the missing attributes via
properties, Coordiantes3D seems to be mainly a speed hack and should not
influence the design too much. One approach would be to make a unified
Point class that takes keyword arguments for x, y, z, r, phi, theta and
calculates the missing parameters either immediately in __init__() or
lazily on attribute access (I use 2D examples througout):

class LazyPoint(object):
def getX(self):
try:
return self._x
except AttributeError:
self._x = self.r * math.cos(self.phi)
return self._x
x = property(getX)

Another option would be to add calculated attributes, e. g. x, y, z to
Polar, (without caching) and construct the CachingPoint aka Coordinates3D
using these:

class Point(object):
""" Shared implementation for Polar, Cartesion, and CachingPoint """
r = property(lambda self: self._r)
phi = property(lambda self: self._phi)
x = property(lambda self: self._x)
y = property(lambda self: self._y)
def __str__(self):
return "r=%s, phi=%s, x=%s, y=%s" % \
(self.r, self.phi, self.x, self.y)

class Polar(Point):
def __init__(self, r, phi):
self._r = r
self._phi = phi
x = property(lambda self: self.r * math.cos(self.phi))
y = property(lambda self: self.r * math.sin(self.phi))

class Cartesian(Point):
def __init__(self, x, y):
self._x = x
self._y = y
r = property(lambda self: math.sqrt(self.x*self.x+self.y*self.y))
phi = property(lambda self: math.atan2(self.y, self.x))

class CachingPoint(Point):
def __init__(self, point):
# as both Polar and Cartesion support the full
# attribute set, no type checking is needed here
self._x = point.x
self._y = point.y
self._r = point.r
self._phi = point.phi

if __name__ == "__main__":
p = Polar(1.0, math.pi/4.0)
print p
print CachingPoint(p)
print "---"
p = Cartesian(3.0, 4.0)
print p
print CachingPoint(p)


 
Reply With Quote
 
Carl Banks
Guest
Posts: n/a
 
      06-09-2004
Sergey Krushinsky <(E-Mail Removed)> wrote in message news:<(E-Mail Removed)>...
> Hello all,
>
> Is there a common way to emulate constructor overloading in Python class?
>
> For instanse, I have 3 classes:
> 1/ Polar - to hold polar coordinates;
> 2/ Cartesian - to hold cartesian coordinates;
> 3/ Coordinates3D, which holds synchronized instances of the both in
> __p__ and __c__ fields respectively.
>
> I want to design Coordinates3D so that when instantiated with Polar
> argument, self.__p__=argument passed to constructor, and self.__c__ is
> calculated. When argument is Cartesian, self.__c__=argument, and
> self.__p__ is calculated. Runtime type checking works, but maybe there
> is a better way?



Polar and Cartesian could both have methods cart() and polar().

x.cart() would return the cartesian representation whether x is
Cartesian, Polar, or the Coordinates3D. If x is Polar, it makes the
conversion.

x.polar() would do likewise returning polar representation.

Then, to initialize Coordinates3D, it could set _p and _c thusly:

self._p = x.polar()
self._c = x.cart()

This will work regardless of whether x is a Polar or Cartesian. You
should define these methods for Coordinates3D, too. (Note: you
shouldn't use variables of the form __xxx__ for regular variables; see
Naming Conventions at http://www.python.org/peps/pep-0008.html)

OTOH, I could see why you might not want to do that. If the point of
having three separate classes is so that you use a polar as a polar,
then maybe you wouldn't want to have it return a cartesian. If that's
so, then just check the types. It won't kill you.


--
CARL BANKS
 
Reply With Quote
 
Sergey Krushinsky
Guest
Posts: n/a
 
      06-11-2004
Thanks to all
I realize that Coordinates3D was not a perfect example, especially in
respect of its design. Anyway, I have learned from your postings some
smart design concepts, which could hardly be implemented in languages
other than Python.

With best regards,
Sergey

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
A constructor calling another constructor (default constructor)? Generic Usenet Account C++ 10 11-28-2007 04:12 AM
RE: Overloading __init__ & Function overloading Iyer, Prasad C Python 4 09-30-2005 08:01 PM
Overloading __init__ & Function overloading Iyer, Prasad C Python 3 09-30-2005 02:17 PM
Re: Overloading __init__ & Function overloading Steve Holden Python 0 09-30-2005 01:58 PM
Re: Overloading __init__ & Function overloading Fredrik Lundh Python 0 09-30-2005 01:53 PM



Advertisments