【问题标题】:Using __add__ operator with multiple arguments in Python在 Python 中使用带有多个参数的 __add__ 运算符
【发布时间】:2018-04-03 18:44:20
【问题描述】:

我正在尝试添加一个带有数字的类对象,但我对如何添加一个带有两个数字的类对象感到困惑。例如,这是我假设的 add 类方法:

class A:
    def __add__(self, b):
        return something

到目前为止我知道如何添加这个:

a = A()
print(a + 1)

但是,如果我想这样添加呢?

a = A()
print(a + 1 + 2)

我应该为 add 类方法使用 *args 吗?

【问题讨论】:

    标签: python class overloading add operator-keyword


    【解决方案1】:

    不,您不能使用多个参数。 Python 分别执行每个+ 运算符,这两个+ 运算符是不同的表达式。

    对于您的示例,object + 1 + 2 确实是 (object + 1) + 2。如果(object + 1) 生成一个具有__add__ 方法的对象,那么Python 将为第二个运算符调用该方法。

    例如,您可以在此处返回另一个 A 实例:

    >>> class A:
    ...     def __init__(self, val):
    ...         self.val = val
    ...     def __repr__(self):
    ...         return f'<A({self.val})>'
    ...     def __add__(self, other):
    ...         print(f'Summing {self} + {other}')
    ...         return A(self.val + other)
    ...
    >>> A(42) + 10
    Summing A(42) + 10
    <A(52)>
    >>> A(42) + 10 + 100
    Summing A(42) + 10
    Summing A(52) + 100
    <A(152)>
    

    【讨论】:

    • 不应该在此处添加 radd 的实现吗?还有,在1+2+3的情况下,是实现(1.__add__(2)).__add__(3)还是1.__add__(2.__add__(3))?
    • @NM:这不是要求,无论如何也不能回答这个问题。
    • @NM: 和 __radd__ 只有在 LHS 拒绝处理操作或 RHS 是 LHS 类型的子类时才会被调用。 1 + 2 + 3(1).__add__(2).__add__(3)
    • @NM:换个说法,对于LHS + RHS,对于not issubclass(type(RHS), type(LHS)),首先调用LHS.__add__(RHS),如果不存在或返回NotImplemented只有这样RHS.__radd__(LHS) 尝试过的。子类例外是为了使现有类型的子类化和“捕获”操作符挂钩成为可能。
    【解决方案2】:

    你会希望你的返回值是一个对象本身,它也支持添加操作,例如:

    class A:
        def __init__(self, value=0):
            self.value = value
    
        def __add__(self, b):
            return A(self.value + b)
    
        def __str__(self):
            return str(self.value)
    
    a = A()
    print(a + 1 + 2)
    

    输出:

    3

    【讨论】:

      【解决方案3】:

      即使有多个值,它也能完美运行,因为每次添加只会添加两个值(在添加多个值时请参阅多个 + 符号):

      class A:
          def __init__(self, value):
              self.a = value
          def __add__(self, another_value):
              return self.a + another_value
      
      
      a = A(1)
      print(a+1+1)
      

      【讨论】:

      • 在这种情况下,最后的添加操作不再由 A 类处理,而是简单地添加 2(由 A.__add__ 返回)和 1。
      • 是的,你是对的,但是因为 1 和 2 是数字,所以应该发生这种情况。如果作者想添加两个类实例,那么示例将不是 a+1 而是 a+b(a 和 b 是 A 的实例)...
      【解决方案4】:

      你总是可以这样做:

      >>> class A:
      ...     def __init__(self, val):
      ...         self.val = val
      ...     def __repr__(self):
      ...         return f'<A({self.val})>'
      ...     def __add__(self, other):
      ...         print(f'Summing {self} + {other}')
      ...         return A(self.val + other)
      ...
      >>> A(42) + 10
      Summing A(42) + 10
      <A(52)>
      >>> A(42) + 10 + 100
      Summing A(42) + 10
      Summing A(52) + 100
      <A(152)>>>> class A:
      ...     def __init__(self, val):
      ...         self.val = val
      ...     def __repr__(self):
      ...         return f'<A({self.val})>'
      ...     def __add__(self, other):
      ...         print(f'Summing {self} + {other}')
      ...         return A(self.val + other)
      ...
      >>> A(42) + 10
      Summing A(42) + 10
      <A(52)>
      >>> A(42) + 10 + 100
      Summing A(42) + 10
      Summing A(52) + 100
      <A(152)>
      

      【讨论】:

      • 这有帮助吗?
      猜你喜欢
      • 1970-01-01
      • 2023-03-08
      • 1970-01-01
      • 2021-04-09
      • 2022-10-13
      • 1970-01-01
      • 2020-09-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多