So, I've written a class to represent vectors called Vector, and i'm trying to write a subclass called Visual_vector that contains additional attributes pertaining to how the vector will be displayed on screen, such as the origin and endpoint of the line to be drawn. My issue is that when I create an instance of Visual_vector, it loses self.origin and self.end_point:
>>> a = Visual_vector((0, 0), (45, 330)) >>> a.x 45 >>> a.y 330 >>> a.length 333.0540496676178 >>> a.origin >>> a.end_point I suspect this might have something to do with my use of getattr and setattr in the super class, but other than that I have no idea what the issue is
Vector class:
class Vector(): """A class to represent a 2D vector""" def __init__(self, tup): self.x = tup[0] self.y = tup[1] # retrieving attributes def __getattr__(self, name): if name == 'vector': # returns the vector as a tuple # (x, y) return (self.x, self.y) elif name == 'length' or name == 'magnitude': # returns the length as a float # sqrt(x^2 + y^2) return float( sqrt(self.x**2 + self.y**2) ) elif name == 'normal': # returns a normalized vector as a tuple # (x/l, y/l) if self.length == 0: return (0, 0) else: x = self.x / self.length y = self.y / self.length return (x, y) #return (self.x / self.length, self.y / self.length) # setting attributes def __setattr__(self, name, value): if name == 'x' or name == 'y': # assign value normally self.__dict__[name] = value elif name == 'length': # |(x, y)| * length # create a new, normalized vector of the same trajectory new_vector = Vector(self.normal) # then multiply it by a scalar to get the desired length self.x = new_vector.x * value self.y = new_vector.y * value elif name == 'vector': # does the same as setting both x and y at the same time if len(value) == 2: # must be a list or tuple self.x = value[0] self.y = value[1] # mathematical operations def __add__(self, other): # (x1 + x2, y1 + y2) x = self.x + other.x y = self.y + other.y return Vector((x, y)) def __iadd__(self, other): return self + other def __sub__(self, other): # (x1 - x2, y1 - y2) x = self.x - other.x y = self.y - other.y return Vector((x, y)) def __isub__(self, other): return self - other Visual_vector class:
class Visual_vector(Vector): """A class to represent the vectors shown on screen""" def __init__(self, origin, end_point): # qualities relative to a coord system Vector.__init__(self, end_point) # qualities relative to the screen self.origin = origin self.end_point = end_point
__setattr__silently refuses to set any attribute other thanx,y,length, orvector.__setattr__-Method because of your observed wired behaviour. Replace it with alength- orvector-property