如何在Python中约束类型为子类的联合类型?
解决方案
要定义能匹配Foobar任意子类,或这些子类联合类型的AnyFoobars,可以通过以下两种方式实现:
1. 基于TypeVar和Union的类型别名
先保留你原来定义的单个子类类型变量,再用Union配合可变参数语法定义支持联合的类型:
from typing import TypeVar, Union class Foobar: pass class FoobarAlpha(Foobar): pass class FoobarBeta(Foobar): pass # 匹配单个Foobar子类的类型变量 AnyFoobar = TypeVar("AnyFoobar", bound=Foobar) # 匹配单个子类或多个子类联合的类型 AnyFoobars = Union[AnyFoobar, ...]
使用示例:
def handle_foobar(item: AnyFoobars) -> None: print(item.__class__.__name__) # 合法调用:单个子类实例 handle_foobar(FoobarAlpha()) handle_foobar(FoobarBeta()) # 合法调用:联合类型实例(由条件表达式生成) handle_foobar(FoobarAlpha() if True else FoobarBeta())
这种方式既能保留具体子类的类型信息,又支持联合类型的场景。
2. 直接使用Foobar基类(简化场景)
如果不需要严格保留子类的具体类型,仅需要确保输入是Foobar或其子类的实例(包括联合类型实例),直接用Foobar作为类型标注即可——类型检查器会自动识别所有子类实例(包括联合类型的实例)都兼容Foobar类型:
def handle_foobar(item: Foobar) -> None: print(item.__class__.__name__) # 同样支持所有合法调用 handle_foobar(FoobarAlpha()) handle_foobar(FoobarBeta()) handle_foobar(FoobarAlpha() if True else FoobarBeta())
注意事项
如果你的需求是匹配类本身(而非实例),比如要接受FoobarAlpha、FoobarBeta这类类型对象,需要结合Type泛型:
from typing import Type def get_subclass(cls: Union[Type[AnyFoobar], ...]) -> None: print(cls.__name__) get_subclass(FoobarAlpha) get_subclass(FoobarBeta)
内容的提问来源于stack exchange,提问作者azmeuk
相关产品推荐
相关产品推荐

