views:

56

answers:

2

I'd like to be able to have the operator of my class interact with regular types in a way that I define. Lets say, for example, I have:

class Mynum(object):
  def __init__(self, x):
   self.x = x
  def __add__(self, other):
   return self.x + other.x

a = Mynum(1)
b = Mynum(2)

print a+b

This works just fine, but now if I try to do:

print a+2

I get an error since an int does not have a member named x. How do I define Mynum + int in the class? This sounds like a job for decorators or metaclasses, but I'm terribly unfamiliar with their usage. This question seems similar, but not quite identical.

+4  A: 
def __add__(self, other):
    if isinstance(other, self.__class__):
        return self.x + other.x
    elif isinstance(other, int):
        return self.x + other
    else:
        raise TypeError("unsupported operand type(s) for +: '{}' and '{}'").format(self.__class__, type(other))
SilentGhost
Thank you, I've never seen `isinstance` before. Is this considered the correct way to do this, or should I use the try/except block proposed by unutbu?
Hooked
The `try… except` clause is fast when no exception is raised, and slow otherwise. Therefore, you can use it if adding two instances of your class is the most common use of the overloaded addition. Otherwise, the `insinstance` approach is good.
EOL
+4  A: 
class Mynum(object):
    def __init__(self, x):
        self.x = x
    def __add__(self, other):
        try:
            return self.x + other.x
        except AttributeError:
            return self.x + other
    __radd__=__add__

a = Mynum(1)
b = Mynum(2)

print(a+b)
# 3
print(a+2)
# 3
print(2+a)
# 3
unutbu