[Tutor] design of Point class

bob gailer bgailer at gmail.com
Sat Aug 21 01:57:40 CEST 2010


  On 8/20/2010 1:55 PM, Gregory, Matthew wrote:
> Wayne Werner wrote:
>> 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
> Thanks all for good suggestions.  I'm intrigued by the idea of subclassing list (suggested by both Bob and Wayne) and using x, y and z as descriptors to the elements in the list.  Obviously, it's important that the descriptors (x,y,z) stay in sync with the list itself so that:
>
>    >>>  p = PointND(1,2,3)
>    >>>  p.x = 10
>    >>>  p
>    [10,2,3]
>
> > From what I understood of the link Wayne sent, I should be able to use __set__ to create this relationship between the labels and the list, but I'm totally lost on how to do this.  It seems like x,y,z need to be instances of descriptor objects who have values that are associated with the list.
>
> In the mean time, I've overridden __setattr__ to enforce this, but it looks a bit crufty.  Any further suggestions are most welcome.
>
> class PointND(list):
>      def __init__(self, *a_list):
>          super(PointND, self).__init__(a_list)
>          if len(self)<= 3:
>              self.x = self[0]
>          if len(self)>= 2 and len(self)<= 3:
>              self.y = self[1]
>          if len(self) == 3:
>              self.z = self[2]
>
>      def __setattr__(self, attr, value):
>          if attr in ('x', 'y', 'z'):
>              self.__dict__[attr] = value
>              if attr == 'x':
>                  self[0] = value
>              elif attr == 'y':
>                  self[1] = value
>              else:
>                  self[2] = value

class PointND(list):
     def __init__(self, *a_list):
         super(PointND, self).__init__(a_list)

     def get(self, ix):
         if len(self)>=  ix + 1:
             return self[ix]
         else:
             raise AttributeError

     def set(self, ix, value):
         if len(self)>=  ix + 1:
             self[ix] = value
         else:
             raise AttributeError

     def getx(self):
         return self.get(0)
     def setx(self, value):
         self.set(0, value)
     x  =  property(getx,  setx)

     def gety(self):
         return self.get(1)
     def sety(self, value):
         self.set(1, value)
     y  =  property(gety,  sety)

# repeat for z



-- 
Bob Gailer
919-636-4239
Chapel Hill NC



More information about the Tutor mailing list