泛型类子类使用时的类型标注问题及解决方案咨询
泛型类结合使用时的mypy类型错误排查与解决
问题描述
我定义了泛型接口Foo[T],实现了继承自Foo[str]的非泛型类Bar,同时创建了泛型类Baz[T1],其方法sirRobin接收Foo[T1]实例和T1类型参数并调用实例方法。单独使用Baz[str]或Baz[int]时类型校验正常,但直接用Baz()结合Bar调用sirRobin时,mypy抛出类型不兼容错误,期望mypy能从调用场景自动推断泛型类型,请问问题出在哪?如何正确标注类型?
代码示例
from typing import Generic, TypeVar T = TypeVar("T") class Foo(Generic[T]): def foo(self, arg: T) -> None: pass class Bar(Foo[str]): def foo(self, arg: str) -> None: print(arg + " boldly runs") T1 = TypeVar("T1") class Baz(Generic[T1]): def sirRobin(self, instance: Foo[T1], param: T1) -> None: instance.foo(param) # 无类型错误,无输出 Baz[str]().sirRobin(Foo(), "she") Baz[int]().sirRobin(Foo(), 1) print("----") # mypy报错: # Argument 1 to "sirRobin" of "Baz" has incompatible type "Bar"; expected "Foo[<nothing>]]" [arg-type] # Argument 2 to "sirRobin" of "Baz" has incompatible type "str"; expected < nothing > [arg-type] # 但程序运行正常 Baz().sirRobin(Bar(), "he")
程序输出
---- he boldly runs
错误原因
当直接实例化Baz()而不显式指定泛型参数T1时,mypy无法自动关联sirRobin方法的两个参数类型:Bar本质是Foo[str],而第二个参数是str类型。mypy的类型推断逻辑在这种场景下不会自动合并两个参数的类型信息,会将T1推断为<nothing>(即无法确定的空类型),导致类型不匹配报错。
解决方案
有两种简洁的修复方式:
- 显式指定Baz的泛型参数:
将Baz().sirRobin(Bar(), "he")修改为Baz[str]().sirRobin(Bar(), "he"),直接告知mypyT1的具体类型为str,此时类型校验完全匹配。 - 利用类型推断的上下文提示:
如果不想显式指定泛型参数,可以通过变量标注类型来辅助mypy推断:baz: Baz[str] = Baz() baz.sirRobin(Bar(), "he")
验证结果
修改后mypy不再抛出类型错误,程序运行逻辑保持不变,输出正确结果。
内容的提问来源于stack exchange,提问作者Árpád Magosányi
相关产品推荐
相关产品推荐

