根据 mypy 文档,如果一个类需要引用自身,它可以使用forward-reference。
这似乎适用于普通类,但我无法让它与继承自 NamedTuple 的类一起使用。
"""
All this code runs without error on Python 3.6
The question is why the 'B' class' __add__ method
raises an error through mypy.
"""
from typing import *
class A:
def __init__(self, x: int) -> None:
self.x = x
def __add__(self, other: 'A') -> 'A':
return type(self)(self.x + other.x)
def __str__(self) -> str:
return f'A(x={self.x})'
A1 = A(1)
A2 = A(2)
A3 = A1 + A2
print(A3)
class B(NamedTuple('B', [('x', int)])):
# The following line will raise an error in mypy
# error: Argument 1 of "__add__" incompatible with supertype "tuple"
def __add__(self, other: 'B') -> 'B':
return type(self)(self.x + other.x)
B1 = B(1)
B2 = B(2)
B3 = B1 + B2
print(B3)
更新:Guido van Rossum 本人已经在 Github 上回答了这个问题。
我不是 100% 确定你想要完成什么,但根据你最初的例子,我猜你想为 B 类重新定义 + 以在 B 的实例上实现元素加法。 mypy 的原因没有默认情况下不支持这个被称为“Liskov 替换原则”(你可以谷歌它以获得解释)。
但是有一个解决方法:将 # type: ignore 放在产生错误的行(def add行)上。这听起来不太好,但是只要您从不将 B 实例传递给假定它是元组并尝试对其进行元组连接的代码,它就会做您想做的事情。