根據mypy文檔,如果一個類需要引用它自己,它可以使用forward-reference。如何實現對從mypy中的NamedTuple繼承的類的方法進行類型檢查?
這對於普通的類似乎很好,但我無法使用從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自己回答了this question on Github。
我不是100%確定你想要完成什麼,但根據你最初的例子,我猜你想重新定義+爲B類實現元素明智的添加B. mypy默認不支持這個的原因是所謂的「Liskov替代原則」(你可以通過谷歌來解釋)。
但是有一個解決方法:在產生錯誤的行上輸入#type:ignore(def add line)。這聽起來不太合適,但只要你不將一個B實例傳遞給假定它是一個元組的代碼並嘗試連接它就可以完成你想要的任務。
這很奇怪。請注意,'B類'已經從'__name__''B'類繼承...也許這是在搞亂事情。所以'__mro__'會變成類似'(,,,)' –
嘗試更改'B'的名字,或者你傳給'namedtuple'的名字。所以像'class B(NamedTuple('SuperB',[('x',int)])): ' –
這可能是相關的:https://github.com/python/mypy/issues/1237 –