Python中如何正确为集合类添加类型提示?
Python集合类类型提示的正确写法
你遇到的类型警告是因为用Union[SurfaceTypeA, SurfaceTypeB]作为TypeVar的bound不合适。bound要求的是一个包含公共成员的单一类型,而Union仅表示T属于几个类型之一,类型检查器无法从中推导出所有分支都具备common_method,因此将s推断为object类型。
以下是两种可行的修正方案:
方案一:定义公共抽象基类
创建一个包含公共方法的抽象基类,让所有Surface类继承它,再将TypeVar绑定到这个基类,类型检查器就能识别公共方法:
from dataclasses import dataclass, field from typing import TypeVar from abc import ABC, abstractmethod @dataclass class BaseSurface(ABC): @abstractmethod def common_method(self) -> None: pass @dataclass class SurfaceTypeA(BaseSurface): def common_method(self) -> None: pass @dataclass class SurfaceTypeB(BaseSurface): def common_method(self) -> None: pass # TypeVar绑定到公共基类 T = TypeVar("T", bound=BaseSurface) @dataclass class SurfaceCollection[T]: _surfaces: list[T] = field(default_factory=list) def run_common_method_on_surfaces(self) -> None: for s in self._surfaces: s.common_method() # 类型检查器可正常识别方法
方案二:使用Protocol(无需修改类继承)
如果不想改动原有类的继承关系,可以用Protocol定义公共方法的接口,将TypeVar绑定到这个Protocol:
from dataclasses import dataclass, field from typing import TypeVar, Protocol # 定义Protocol声明公共方法 class SurfaceProtocol(Protocol): def common_method(self) -> None: ... @dataclass class SurfaceTypeA: def common_method(self) -> None: pass @dataclass class SurfaceTypeB: def common_method(self) -> None: pass # TypeVar绑定到Protocol T = TypeVar("T", bound=SurfaceProtocol) @dataclass class SurfaceCollection[T]: _surfaces: list[T] = field(default_factory=list) def run_common_method_on_surfaces(self) -> None: for s in self._surfaces: s.common_method() # 类型检查器可正常识别方法
内容的提问来源于stack exchange,提问作者Ed May
相关产品推荐
相关产品推荐

