使用isinstance检测StrEnum类型失败,求Pythonic解决方案
解决TypedDict中StrEnum类型的验证问题
问题核心
当AnimalInfo TypedDict的字段类型定义为StrEnum(比如Animal),但测试数据传入的是字符串值(如"CAT")时,直接用isinstance("CAT", Animal)会返回False——因为字符串不是枚举类的实例,尽管它是枚举的有效值。
简洁Pythonic的解决方案
无需单独针对StrEnum写分支判断,我们可以利用枚举类的可实例化特性,实现一个兼容普通类型与枚举类型的通用验证工具:
1. 通用类型检查函数
先尝试将值转换为预期类型(合法枚举值能成功实例化),转换失败则回退到isinstance检查:
from typing import Any, Type from enum import Enum def is_valid_value(value: Any, expected_type: Type) -> bool: try: # 枚举合法值可成功实例化,普通类型转换也不会报错 expected_type(value) return True except (ValueError, TypeError): # 转换失败时,检查是否为预期类型的实例 return isinstance(value, expected_type)
2. TypedDict整体验证函数
结合上述工具函数,遍历TypedDict的所有字段完成验证:
from typing import get_type_hints def validate_typed_dict(data: dict, typed_dict_cls) -> bool: field_types = get_type_hints(typed_dict_cls) # 先校验字段数量与名称是否匹配 if set(data.keys()) != set(field_types.keys()): return False # 逐个验证字段类型合法性 for field, expected_type in field_types.items(): if not is_valid_value(data[field], expected_type): return False return True
3. 测试示例
假设你的类型定义如下:
from typing import TypedDict from enum import StrEnum class Animal(StrEnum): CAT = "CAT" DOG = "DOG" class AnimalInfo(TypedDict): animal_type: Animal name: str
测试时直接调用验证函数即可:
test_data = {"animal_type": "CAT", "name": "Whiskers"} assert validate_typed_dict(test_data, AnimalInfo) # 验证通过 invalid_data = {"animal_type": "BIRD", "name": "Tweety"} assert not validate_typed_dict(invalid_data, AnimalInfo) # 验证失败
方案优势
- 对
StrEnum:合法字符串值可通过expected_type(value)成功实例化枚举,直接返回True; - 对普通类型(如
str、int):转换操作无副作用,或通过isinstance完成校验; - 全程无需单独处理
StrEnum,逻辑通用、简洁且符合Python风格。
内容的提问来源于stack exchange,提问作者harryjulian
相关产品推荐
相关产品推荐

