#!/usr/bin/python class Point(object): def __init__(self, x, y): assert isinstance(x, int) assert isinstance(y, int) self.x = x self.y = y def __repr__(self): return "Point(x=%s, y=%s)" % (self.x, self.y) class Ellipse(object): def __init__(self, a, b, ctr): assert isinstance(a, int) assert isinstance(b, int) assert isinstance(ctr, Point) assert a >= b self.a = a self.b = b self.ctr = ctr def __repr__(self): return "Ellipse(a=%s, b=%s, ctr=%r)" % (self.a, self.b, self.ctr) def __setattr__(self, name, value): if not hasattr(self, 'ctr'): self.__dict__[name] = value return if name == 'a': assert value >= self.b elif name == 'b': assert self.a >= value self.__dict__[name] = value class Circle(Ellipse): def __init__(self, r, ctr): assert isinstance(r, int) assert isinstance(ctr, Point) super(Circle, self).__init__(r, r, ctr) self.r = r def __setattr__(self, name, value): if hasattr(self, 'r') and (name == 'a' or name == 'b'): raise KeyError elif name == 'r': super(Circle, self).__setattr__('a', value) super(Circle, self).__setattr__('b', value) else: super(Circle, self).__setattr__(name, value) def __repr__(self): return "Circle(r=%s, ctr=%r)" % (self.a, self.ctr) if __name__ == '__main__': p = Point(0, 0) e = Ellipse(4, 2, p) c = Circle(1, p) print("Initial") print(p) print(e) print(c) print() e = c print("After e = c") print(e) print(c) print() e.a = 3 print("After e.a = 3") print(e) print(c)