How do I implement polymorphic arithmetic operators pythonicly?
polymorphism, python, type-conversion
Solution
The "Pythonic" way is to "ask forgiveness rather than permission" - that is, instead of checking the type beforehand, try to add and, if it fails, catch the exception and deal with it, like so:
class GpsPoint(object):
"""A class for representing gps coordinates"""
def __init__(self, x, y, z):
self.x = x
self.y = y
self.z = z
def __add__(self, other):
try:
return GpsPoint(self.x + other.x, self.y + other.y, self.z + other.z)
except AttributeError:
return GpsPoint(self.x + other, self.y + other, self.z + other)
def __radd__(self, other):
try:
return GpsPoint(self.x + other.x, self.y + other.y, self.z + other.z)
except AttributeError:
return GpsPoint(self.x + other, self.y + other, self.z + other)
def __str__(self):
return "%d, %d, %d" % (self.x, self.y, self.z)
Problem
I'm trying to create a class that will allow me to add/multiply/divide objects of the same class together or add/multiply numeric arguments to each member of the class So my class is for coordinates (I am aware there are great packages out there that do everything I want better than I could ever hope to on my own, but now I'm just curious). ``` class GpsPoint(object): """A class for representing gps coordinates""" def __init__(self, x, y, z): self.x = x self.y = y self.z = z def __add__(self, other): return GpsPoint(self.x + other.x, self.y + other.y, self.z + other.z) def __radd__(self, other): return GpsPoint(self.x + other, self.y + other, self.z + other) def __str__(self): return "%d, %d, %d" % (self.x, self.y, self.z) ``` This was my original attempt. I found it worked, but only if I used a numeric argument first ``` >>foo = GpsPoint(1,2,3) >>print 5 + foo 6, 7, 8 >>print foo + 5 AttributeError: 'int' object has no attribute 'x' ``` So, what is the pythonic way to do this, is there a pythonic way, is this just silly? I see what the philosophical problem is with using `isinstance()` and I know I could toss in a `try` `except` block I'm just curious how I should go about this.