如何创建模拟isinstance的TypeGuard以解决API对象类型检查问题
为自定义isinstance函数添加TypeGuard支持
问题背景
当检查API创建的对象时,调用内置isinstance(obj, MyClass)可能触发TypeError,因此编写了带异常捕获的自定义函数:
def is_instance(obj: Any, class_or_tuple: Any) -> bool: try: return isinstance(obj, class_or_tuple) except TypeError: return False
但该函数缺少TypeGuard支持,导致类型检查器无法识别类型窄化逻辑,比如以下代码会报错:
def my_process(api_obj: int | str) -> None: if is_instance(api_obj, int): process_int(api_obj) # 类型检查器提示:Type int | str cannot be assigned to parameter else: process_str(api_obj)
解决方案
通过引入泛型TypeVar和TypeGuard,为自定义函数添加类型提示,让类型检查器能够识别类型窄化逻辑:
修改后的完整代码
from typing import Any, Type, TypeGuard, TypeVar, Tuple, Union # 定义泛型类型变量,用于关联输入的类类型和返回的类型断言 T = TypeVar('T') def is_instance(obj: Any, class_or_tuple: Union[Type[T], Tuple[Type[T], ...]]) -> TypeGuard[T]: try: return isinstance(obj, class_or_tuple) except TypeError: return False
作用说明
TypeVar('T')创建泛型变量,用于关联输入的类/类元组与返回的类型断言Union[Type[T], Tuple[Type[T], ...]]限定第二个参数可以是单个类,或是多个类组成的元组TypeGuard[T]告诉类型检查器:当函数返回True时,obj的类型可被窄化为T
验证示例
修改后,原示例代码中的类型检查报错会消失:
def my_process(api_obj: int | str) -> None: if is_instance(api_obj, int): process_int(api_obj) # 类型检查器自动识别api_obj为int类型 else: process_str(api_obj) # 类型检查器自动识别api_obj为str类型
同时也支持多类元组的场景:
def handle_obj(obj: int | str | bool) -> None: if is_instance(obj, (int, str)): # obj类型被窄化为int | str pass
内容的提问来源于stack exchange,提问作者Amour Spirit
相关产品推荐
相关产品推荐

