On Sat, 10 Nov 2012 20:33:05 +0100, Jennie wrote: [...] > I propose three solutions. The first one: > > >>> class Point: > ... def __init__(self, x=0, y=0): > ... self.x = x > ... self.y = y > ... def __sub__(self, other): > ... return Point(self.x - other.x, self.y - other.y)
Don't do this, because it breaks subclassing. Your instance should dynamically get it's own class, not hard-code the name of Point. return self.__class__(self.x - other.x, self.y - other.y) That way, when you subclass Point, you can do arithmetic on the subclass instances and they will do the Right Thing. Note: Python's builtin numeric types don't do this, and it is a damned nuisance: py> class MyInt(int): ... pass ... py> a, b = MyInt(23), MyInt(42) py> assert type(a) is MyInt and type(b) is MyInt py> type(a + b) <type 'int'> Back to your class: > ... def distance(self, point=None): > ... p = point if point else Point() > ... return math.sqrt((self - p).x ** 2 + (self - p).y ** 2) Almost but not quite. I assume that, in a full Point class, you would want Point(0, 0) to count as false in a boolean context. (A "falsey" value, like None, [], 0.0, etc.) So change the test to an explicit test for None, not just any falsey value: if point is None: point = self.__class__() # Allow subclassing to work. > The second one: > > >>> class Point: > ... def __init__(self, x=0, y=0): > ... self.x = x > ... self.y = y > ... def __sub__(self, other): > ... return Point(self.x - other.x, self.y - other.y) > ... > >>> def distance(self, point=Point()): > ... return math.sqrt((self - point).x ** 2 + (self - point).y ** 2) > ... > >>> Point.distance = distance Cute, but ugly and messy. You can inject methods into a class, of course, but that's an awfully big hammer to crack this tiny little nut. Your first solution is better. Here is a variation which, according to your tastes, may count as more or less ugly: inject the default value into the method: class Point: def distance(self, other=None): # None is a placeholder delta = self - other return math.sqrt(delta.x ** 2 + delta.y ** 2) Point.distance.__defaults__ = (Point(),) # In Python 2, use: # Point.distance.__func__.func_defaults = (Point(),) -- Steven -- http://mail.python.org/mailman/listinfo/python-list