Method default argument whose type is the class not yet defined

Terry Reedy tjreedy at udel.edu
Sat Nov 10 21:29:39 CET 2012


On 11/10/2012 2:33 PM, Jennie wrote:
> What is the best solution to solve the following problem in Python 3.3?
>
> import math
>  >>> 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 the distance from `point`."""
> ...         return math.sqrt((self - point).x ** 2 + (self - point).y ** 2)
> ...
> Traceback (most recent call last):
>    File "<stdin>", line 1, in <module>
>    File "<stdin>", line 5, in Point
> NameError: name 'Point' is not defined
>
> 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)
> ...     def distance(self, point=None):
> ...         p = point if point else Point()
> ...         return math.sqrt((self - p).x ** 2 + (self - p).y ** 2)
> ...
>  >>> p = Point()
>  >>> p.distance()
> 0.0
>  >>> p.distance(Point(3, 4))
> 5.0

What I do not like about this one is that it creates a new 0 point each 
time one is needed. Two solutions:

change Point() to point0 in the distance function and create
point0 = Point()
after the class.

-or-
instead of p = line,
px,py = point.x, point.y if point else 0.0, 0.0


> 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
>  >>> p = Point()
>  >>> p.distance(Point(3, 4))
> 5.0

my first thought


> The last one:
>
>  >>> class Point:
> ...     def __init__(self, x=0, y=0):
> ...         self.x = x
> ...         self.y = y
> ...         Point.distance = distance
> ...     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)
> ...
>  >>> p = Point()
>  >>> p.distance(Point(3, 4))
> 5.0
>
> Is there a better solution?


-- 
Terry Jan Reedy



More information about the Python-list mailing list