On Fri, Aug 20, 2010 at 10:45 AM, Gregory, Matthew < matt.greg...@oregonstate.edu> wrote:
> Hi all, > > I often struggle with object design and inheritance. I'd like opinions on > how best to design a Point class to be used in multiple circumstances. > > I typically deal with geographic (either 2D or 3D) data, yet there are > occasions when I need n-dimensional points as well. My thought was to > create a superclass which was an n-dimensional point and then subclass that > to 2- and 3-dimensional cases. The rub to this is that in the n-dimensional > case, it probably makes most sense to store the actual coordinates as a list > whereas with the 2- and 3-D cases, I would want 'named' variables, such as > x, y, z. > > Here's a (very rough) first cut at the constructor and a generic distance > function for the n-dimensional case: > > class PointND(object): > def __init__(self, a_list): > self.a_list = a_list[:] > > def distance(self, right): > assert(len(self.coord) == len(right)) > squared_diffs = [(i-j)*(i-j) for (i,j) in zip(self.coord, right)] > return math.sqrt(sum(squared_diffs)) > > But how can I subclass this in such a way to be able to: > > 1) Have named variables in the 2- and 3-D cases > 2) Be able to initialize with separate passed values, e.g. 'p = > Point2D(3.0, 5.0)' > rather than passing in a list > class Point2D(PointND): def __init__(self, x = 0, y = 0): super(Point2D, self).__init__([x,y]) self.x = 0 self.y = 0 though you wouldn't be able to directly modify the values, or you'll lose the distance function. You'd have to create setter functions, and as such should rename x and y to _x and _y, to indicate that sure you *can* touch these, but really you shouldn't. For the 3d, you'd just add a z param, although to really generalize your ND class you could do this instead: class PointND(object): def __init__(self, x=0, y=0, z=0, a_list=None): if a_list is not None: self.a_list = a_list[:] self.x = x self.y = y self.z = z def coords(self): return [self.x, self.y, self.z] + self.a_list ... Then your subclass takes less effort: class Point2D(PointND): def __init__(self, x=0, y=0): super(Point2D, self).__init__(x,y) and this allows you to access point.x, point.y, and point.z directly. Of course you could also subclass list with ND and just use descriptors for self[0], self[1], and self[2]: http://users.rcn.com/python/download/Descriptor.htm HTH, Wayne
_______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor