在Python中重载增强算术赋值

7 投票
3 回答
883 浏览
提问于 2025-04-15 19:18

我刚开始学Python,所以如果这个问题很傻,请多包涵。

为了完成一个作业,我需要为一个叫myInt的类重载增强型算术赋值运算符(比如+=, -=, /=, *=, **=, %=)。我查了Python的文档,得到了以下代码:

def __iadd__(self, other):

    if isinstance(other, myInt):
        self.a += other.a
    elif type(other) == int:
        self.a += other
    else:
        raise Exception("invalid argument")

这里的self.a和other.a指的是每个类实例中存储的整数。我尝试了以下测试,但每次得到的结果都是'None',而不是我期待的值5:

c = myInt(2)
b = myInt(3)
c += b
print c

有没有人能告诉我为什么会这样?谢谢大家。

3 个回答

1

是的,你需要写“return self”,它看起来是这样的:

def __iadd__(self, other):
    if isinstance(other, myInt):
        self.a += other.a
        return self
    elif type(other) == int:
        self.a += other
        return self
    else:
        raise Exception("invalid argument")
7

在Python中,增强运算符需要返回最终的值,这个值会被赋给它所调用的名字,通常情况下(就像你提到的)是self。和所有Python的方法一样,如果没有写返回语句,就会默认返回None

另外,

  • 千万不要抛出Exception,因为这会让你很难捕捉到错误。要是你写了except Exception,那就会捕捉到所有的异常。在这种情况下,你应该使用ValueError或者TypeError
  • 不要用type(foo) == SomeType来检查类型。在这种情况下(以及几乎所有情况),使用isinstance会更好,或者至少效果相同。
  • 每当你创建自己的类型,比如myInt,你应该用大写字母来命名,这样大家就能认出这是一个类名。
14

你需要在你的方法里加上 return self。解释如下:

当你使用 a += b 这个操作时,如果 a 的类型有一个特别的方法叫 __iadd__,那么这个操作的意思是:

  a = a.__iadd__(b)

所以,如果 __iadd__ 返回的不是 self,那么在这个操作完成后,a 就会被绑定到返回的那个值上。因为你没有加 return 语句,你写的方法就相当于一个返回 None 的方法。

撰写回答