Python如何注解类及其子类类型的参数?不使用Union
为类或其子类的参数添加类型注解(不用Union)
方案1:直接用父类作为类型注解
Python的类型检查器(比如mypy、pyright)天然支持子类赋值给父类类型的变量,直接把父类Point作为参数注解即可——不管是Point实例还是它的子类(比如Segment)实例,都能通过类型检查:
class Point: def __init__(self, x, y): self.x = x self.y = y class Segment(Point): def __init__(self, point1, point2): super().__init__(point1.x, point1.y) # 修正原示例__init__拼写错误,调用父类构造方法 self.p1 = point1 self.p2 = point2 def random_function(point_or_segment: Point): pass
调用random_function(Point(1,2))或random_function(Segment(Point(0,0), Point(1,1)))都完全合规,这是最简洁的写法。
方案2:用TypeVar绑定父类(更明确的约束)
如果需要更清晰地标注「参数必须是Point或它的子类」,可以使用typing.TypeVar(Python3.9+也可从collections.abc导入),通过bound参数指定父类:
from typing import TypeVar # 定义绑定到Point的类型变量 PointSubtype = TypeVar('PointSubtype', bound=Point) class Point: def __init__(self, x, y): self.x = x self.y = y class Segment(Point): def __init__(self, point1, point2): super().__init__(point1.x, point1.y) self.p1 = point1 self.p2 = point2 def random_function(point_or_segment: PointSubtype): pass
这种方式在泛型场景更实用,比如函数需要返回和参数同类型的实例时,能保留具体的子类类型信息,不会被降级为父类类型。
小提醒
原示例中Segment继承Point的逻辑并不合理(线段与点并非继承关系),此处仅遵循原示例结构编写;实际开发中需确保类的继承设计符合面向对象原则。另外要保证类型检查器配置正确,才能自动识别子类与父类的类型兼容性。
内容的提问来源于stack exchange,提问作者L Maxime
相关产品推荐
相关产品推荐

