简体   繁体   中英

How to get __add__ called

class C(object):
  def __init__(self, value):
    self.value = value

  def __add__(self, other):
    if isinstance(other, C):
      return self.value + other.value
    if isinstance(other, Number):
      return self.value + other
    raise Exception("error")


c = C(123)

print c + c

print c + 2

print 2 + c

obviously, the first two print statements will work and the third one fails because int. add () cannot deal with a class C instance.

246
125
    print 2 + c
TypeError: unsupported operand type(s) for +: 'int' and 'C'

Is there a way to get around this, so 2+c will cause C. add () to be called?

You need to add __radd__ as well to handle the reverse case:

def __radd__(self, other):
    if isinstance(other, C):
        return other.value + self.value
    if isinstance(other, Number):
        return other + self.value
    return NotImplemented

and note that you should not raise an exception; return the NotImplemented singleton instead. That way the other object could still try to support __add__ or __radd__ for your object and would be given a chance to implement addition too.

When you try to add two types a and b , Python first tries to call a.__add__(b) ; if that call returns NotImplemented , b.__radd__(a) is attempted instead.

Demo:

>>> from numbers import Number
>>> class C(object):
...     def __init__(self, value):
...         self.value = value
...     def __add__(self, other):
...         print '__add__ called'
...         if isinstance(other, C):
...             return self.value + other.value
...         if isinstance(other, Number):
...             return self.value + other
...         return NotImplemented
...     def __radd__(self, other):
...         print '__radd__ called'
...         if isinstance(other, C):
...             return other.value + self.value
...         if isinstance(other, Number):
...             return other + self.value
...         return NotImplemented
... 
>>> c = C(123)
>>> c + c
__add__ called
246
>>> c + 2
__add__ called
125
>>> 2 .__add__(c)
NotImplemented
>>> 2 + c
__radd__ called
125

You need to implement __radd__ on the class.

def __radd__(self, other):
    return self.value + other

This gets called automatically, since the int class will raise a NotImplemented error

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM