`__eq__` 使用属性时如何注解?

How to annotate `__eq__` when it uses an attribute?

给定以下class,我应该如何注释__eq__

class Foo(object):
    def __init__(self, bar):
        self.bar = bar

    def __eq__(self, other):
        return Foo.bar == other.bar

使用 __eq__(self, other: Foo) -> bool 会导致 mypy 错误:

Argument 1 of "__eq__" is incompatible with supertype "object"; supertype defines the argument type as "object"

并使用 __eq__(self, other: object) -> bool 会导致 mypy 错误:

"object" has no attribute "bar"

我该怎么办?

建议__eq__适用于任意对象。在此示例中,您需要先确保 otherFoo class 的成员:

def __eq__(self, other: object) -> bool:
    if not isinstance(other, Foo):
        return NotImplemented
    return Foo.bar == other.bar

object.__eq__() 必须处理任何类型的对象,而不仅仅是您自己的 class。 Return NotImplemented 对于您不想处理的类型,因此 Python 可以询问右侧操作数是否要处理相等性测试。

根据 Python typeshed guidelines:

other 参数注释为 object
def __eq__(self, other: object) -> bool:
    if not isinstance(other, Foo):
        return NotImplemented
    return Foo.bar == other.bar

other 设置为 object 本质上告诉类型检查器任何继承自 object 的东西(在 Python 中是 everything ) 是可以接受的。 isinstance(other, Foo) 测试告诉类型检查器,任何到达函数最后一行的对象不仅是 object 的实例,而且特别是 Foo 的实例或进一步的子实例class.