【问题标题】:How to get __add__ called如何调用 __add__
【发布时间】:2013-10-10 11:34:11
【问题描述】:
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

显然,前两个 print 语句将起作用,而第三个则失败,因为 int.add() 无法处理 C 类实例。

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

有没有办法解决这个问题,所以 2+c 会导致 C.add() 被调用?

【问题讨论】:

    标签: python python-2.7 numbers


    【解决方案1】:

    您还需要添加__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 单例。这样,other 对象仍然可以为您的对象尝试支持__add____radd__,并且也将有机会实现加法。

    当你尝试添加ab这两种类型时,Python首先尝试调用a.__add__(b);如果该调用返回NotImplemented,则尝试使用b.__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
    

    【讨论】:

      【解决方案2】:

      你需要在类上实现__radd__

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

      这会自动调用,因为 int 类会引发 NotImplemented 错误

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-01-26
        • 2016-08-15
        • 1970-01-01
        • 2022-11-17
        • 1970-01-01
        • 1970-01-01
        • 2012-10-31
        • 1970-01-01
        相关资源
        最近更新 更多