Python中如何从Union类型移除单个类型?类似TypeScript的Omit
如何从Python Union类型中移除指定成员?
Python标准库的typing模块没有提供TypeScript那种直接的Omit语法来从Union类型里剔除成员,但可以通过以下方法实现类似需求,避免重复编写Union定义:
1. 利用标准库的类型属性实现
Python 3.10+支持|语法定义Union类型,这类类型会暴露__args__属性存储所有成员类型。你可以直接过滤这个属性来生成新的Union:
from typing import TypeAlias from decimal import Decimal NUMBER_T = int | float | Decimal # 过滤掉int,生成新的Union类型别名 DECIMAL_T: TypeAlias = Union[t for t in NUMBER_T.__args__ if t is not int]
这种写法能被mypy等静态类型检查工具正确识别,也支持运行时操作。如果需要复用逻辑,可以封装成辅助函数:
from typing import Union, TypeAlias def omit_from_union(union_type: type, remove_type: type) -> type: # 提取Union的所有成员,处理非Union类型的边界情况 union_members = getattr(union_type, '__args__', (union_type,)) filtered_members = tuple(t for t in union_members if t is not remove_type) return Union[filtered_members] if filtered_members else type(None) # 使用示例 NUMBER_T = int | float | Decimal DECIMAL_T: TypeAlias = omit_from_union(NUMBER_T, int)
2. 借助第三方库实现泛型操作
如果需要更通用的泛型写法,可以使用typing-extensions库的条件类型工具,不过对于多成员Union,依然需要结合__args__来过滤:
from typing_extensions import Conditional from typing import Union, TypeAlias, TypeVar from decimal import Decimal T = TypeVar('T') U = TypeVar('U') # 定义泛型工具类型,用于从二元Union中移除指定类型 OmitFromUnion = Conditional[Union[T, U], T, U] # 针对多成员Union的实际使用 NUMBER_T = int | float | Decimal DECIMAL_T: TypeAlias = Union[t for t in NUMBER_T.__args__ if t is not int]
目前Python没有内置运算符(比如^)来直接实现Union成员的移除,上述方案已经是最接近TypeScript Omit体验的实现方式。
内容的提问来源于stack exchange,提问作者sedrubal
相关产品推荐
相关产品推荐

