我正在尝试向现有包添加类型注释,显然我错过了一些重要的东西。我有一个抽象超类和子类。超类应该是通用的,而子类应该是针对特定类型的。这是一个简单的例子,如果我看到的话,以及我想看到的:
from typing import Generic, TypeVar
T = TypeVar("T")
class A(Generic[T]):
def method(self, arg: T):
...
class B(A[int]):
def method(self, arg):
reveal_locals()
预期(或至少希望):
GenericTest.py:11: note: Revealed local types are:
GenericTest.py:11: note: arg: int
GenericTest.py:11: note: self: Any
得到:
GenericTest.py:11: note: Revealed local types are:
GenericTest.py:11: note: arg: Any
GenericTest.py:11: note: self: Any
您需要为子类中的方法添加类型注释。这样做:
from typing import Generic, TypeVar
T = TypeVar("T")
class A(Generic[T]):
def method(self, arg: T) -> None:
...
class B(A[int]):
def method(self, arg: int) -> None:
reveal_locals()
...导致预期输出:
test.py:11: note: Revealed local types are:
test.py:11: note: arg: builtins.int
test.py:11: note: self: test.B
如果函数没有使用类型提示进行注释,mypy 将将该函数视为动态类型,并假设其所有参数都是类型
Any
。
如果您希望 mypy 在您忘记这样的输入提示时发出警告,请使用
--disallow-untyped-defs
命令行标志 运行 mypy - 也可以使用 --disallow-incomplete-defs
来进行良好的测量。或者,使用 --strict
标志运行 mypy,它会自动启用上述两个标志(以及更多)。
reveal_locals()
打印 mypy 在调用所在范围内推断出的变量类型。当在子类中重新定义方法时,您也会覆盖注释(当没有显式给出参数注释时,默认使用Any
)
这可能更清楚:
class A(Generic[T]):
def method(self, arg: T):
...
class B(A[int]):
def method(self, arg):
pass
B().method('')
上面的代码对于 mypy 来说没问题,但是下面的代码给出了错误:
class C(A[int]):
pass
C().method('')
error: Argument 1 to "method" of "A" has incompatible type "str"; expected "int"