469,587 Members | 2,153 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,587 developers. It's quick & easy.

Constructor overloading

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

Jul 18 '05 #1
2 5090
"Sergey Krushinsky" <lu******@comail.ru> wrote in message
news:ma*************************************@pytho n.org...
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

Jul 18 '05 #2
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)
Jul 18 '05 #3

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

8 posts views Thread by Sam Sungshik Kong | last post: by
31 posts views Thread by Peter E. Granger | last post: by
14 posts views Thread by Klaus Löffelmann | last post: by
7 posts views Thread by Doug | last post: by
7 posts views Thread by coinjo | last post: by
12 posts views Thread by Rahul | last post: by
reply views Thread by suresh191 | last post: by
4 posts views Thread by guiromero | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.