如何检测参数是否为Pydantic TypeAdapter可接受的类型定义
判断参数是否为Pydantic TypeAdapter可接受的类型定义
最可靠的方法:直接尝试实例化TypeAdapter
既然核心需求是判断TypeAdapter本身能否处理该类型,最直接且准确的方式就是尝试用目标类型创建TypeAdapter实例,通过捕获异常来验证。Pydantic内部已经封装了所有可接受类型的校验逻辑,不需要手动覆盖所有场景。
示例代码:
from pydantic import TypeAdapter def is_valid_type_for_typeadapter(type_def): try: TypeAdapter(type_def) return True except Exception: return False # 测试验证 print(is_valid_type_for_typeadapter(int)) # True print(is_valid_type_for_typeadapter(int|str)) # True print(is_valid_type_for_typeadapter(list[str|int])) # True print(is_valid_type_for_typeadapter(typing.Union[int, str])) # True print(is_valid_type_for_typeadapter(typing.Literal[10,20,30])) # True print(is_valid_type_for_typeadapter(None)) # False
手动类型检查方案(按需选择)
如果不想通过异常捕获实现,需要手动覆盖TypeAdapter支持的所有类型类别,以下是关键场景的判断逻辑:
- 基础原生类型:
isinstance(type_def, type),比如int、str、list这类内置类型。 - Python 3.10+联合类型(|语法):
isinstance(type_def, types.UnionType),对应int|str这类写法。 - typing.Union类型:用
typing.is_union(type_def)判断,对应typing.Union[int, str]。 - 泛型别名:比如
list[str],用isinstance(type_def, types.GenericAlias)判断;对于老版本typing.List[str],可结合typing.get_origin(type_def)识别泛型。 - Literal类型:通过
typing.get_origin(type_def) is typing.Literal判断。
示例代码:
import types import typing def is_valid_type_for_typeadapter(type_def): # 基础类型 if isinstance(type_def, type): return True # 3.10+联合类型 if isinstance(type_def, types.UnionType): return True # typing.Union if typing.is_union(type_def): return True # 泛型别名(list[str]、dict[int, str]等) if isinstance(type_def, types.GenericAlias): return True # Literal类型 if typing.get_origin(type_def) is typing.Literal: return True # 其他支持的泛型(Optional、Tuple等,本质是Union或泛型) origin = typing.get_origin(type_def) if origin in (typing.List, typing.Dict, typing.Tuple, typing.Optional): return True return False
原方案失效原因
你之前的判断逻辑覆盖不全:
int|str属于types.UnionType,既不是types.GenericAlias也不是原生type;typing.Literal[10,20,30]不属于type或types.GenericAlias范畴,必须通过typing.get_origin识别。
内容的提问来源于stack exchange,提问作者VPfB
相关产品推荐
相关产品推荐

