2
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

明らかに、最初の 2 つの print ステートメントは機能しますが、3 番目のステートメントは失敗します。add () はクラス C インスタンスを処理できません。

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

これを回避する方法はありますか? 2+c で C. add () が呼び出されますか?

4

2 に答える 2

5

__radd__逆のケースを処理するためにも追加する必要があります。

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

また、例外を発生させてはならないことに注意してください。NotImplemented代わりにシングルトンを返します。そうすれば、他のオブジェクトはまだあなたのオブジェクトをサポートしようとすることができ__add____radd__追加も実装する機会が与えられます。

2 つのタイプ と を追加しようとするab、Python は最初にa.__add__(b);を呼び出そうとします。その呼び出しが を返す場合、代わりNotImplementedb.__radd__(a)が試行されます。

デモ:

>>> 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
于 2013-10-10T11:36:55.490 に答える
2

__radd__クラスに実装する必要があります。

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

NotImplementedint クラスはエラーを発生させるため、これは自動的に呼び出されます。

于 2013-10-10T11:36:07.340 に答える