我使用的是Python 3.5.1和新发布的MyPy v0.4.1静态类型分析器。
我有一些更复杂的代码,我已经简化为重现错误所需的最简单的python类:
class MyObject(object):
def __init__(self, value: int=5) -> None:
self.value = value
def __eq__(self, other: MyObject) -> bool:
return self.value == other.value
运行类型检查器mypy test.py
会产生以下错误:
test.py: note: In class "MyObject":
test.py:5: error: Argument 1 of "__eq__" incompatible with supertype "object"
我基于these docs的理论是,对象上的__eq__
和__ne__
已经定义了类型,这与我的子类重新定义这些类型有冲突。我的问题是如何定义这些类型以确保使用我选择的类型对__eq__
进行类型检查。
答案 0 :(得分:7)
==
应该采用任意其他对象,而不仅仅是您类型的对象。如果它无法识别其他对象,则应返回NotImplemented
:
class MyObject(object):
def __init__(self, value: int=5) -> None:
self.value = value
def __eq__(self, other: object) -> bool:
if not isinstance(other, MyObject):
return NotImplemented
return self.value == other.value
此外,如果您需要在自己的正文中引用MyObject
类型提示,则需要使用字符串'MyObject'
代替MyObject
。 MyObject
尚不存在。
答案 1 :(得分:3)
您对文档的阅读是正确的 - 您需要为方法(__eq__
)提供与基类(object
)中相同的签名,或者更宽松的方法
原因是因为您的MyObject
是[{1}}的子类型,object
可以传递到任何需要MyObject
的地方......这意味着该代码可以将其与任何其他object
进行比较,并且类型检查器没有合法的方式进行投诉。因此,为了反映这一点,您必须编写object
以期望任何__eq__
。
你可以做的是在方法的正文中,检查类型并返回(或引发异常):
object
然后作为those docs say,Mypy非常聪明,在检查之后,它会知道if not isinstance(other, MyObject):
return False
是other
并相应地对待它。
答案 2 :(得分:-1)
使用“ isinstance()”的测试仅在没有继承的情况下才有效,如果存在继承,则您需要在派生类中重写 eq 或使用type(self)!= type(other)