如何在Python中创建可被静态类型检查器识别的自定义类型断言
实现支持静态类型缩窄的自定义类型校验函数
核心方案:使用TypeGuard标注类型校验函数
Python typing体系中提供了TypeGuard专门用于标记自定义类型校验函数的返回值,当函数返回True时,静态类型检查器(MyPy、Pyright等)会自动将输入参数的类型缩窄到TypeGuard指定的类型。
针对你给出的示例,只需要修改ComplexTypeAssertion的返回值标注即可:
from typing import TypeGuard def ComplexTypeAssertion(data: object) -> TypeGuard[list[str]]: return isinstance(data, list) and all(isinstance(value, str) for value in data)
修改后在if ComplexTypeAssertion(myData)分支内,静态检查器会自动识别myData的类型为list[str],reveal_type会输出正确的缩窄结果。
复杂场景使用示例(TypedDict校验)
该方案完全支持自定义复杂类型的校验,比如常见的TypedDict结构校验场景:
from typing import TypedDict, TypeGuard # 定义需要校验的TypedDict结构 class ApiResponse(TypedDict): code: int message: str data: dict[str, str] def is_valid_api_response(obj: object) -> TypeGuard[ApiResponse]: if not isinstance(obj, dict): return False return ( "code" in obj and isinstance(obj["code"], int) and "message" in obj and isinstance(obj["message"], str) and "data" in obj and isinstance(obj["data"], dict) and all(isinstance(k, str) and isinstance(v, str) for k, v in obj["data"].items()) )
在if is_valid_api_response(resp)分支中,静态检查器会自动将resp识别为ApiResponse类型,无需额外的强制类型转换。
注意事项
- Python 3.10及以上版本可以直接从
typing导入TypeGuard,3.10以下版本需要安装typing_extensions依赖,从typing_extensions import TypeGuard使用,功能完全一致。 - 静态检查器不会校验你运行时的校验逻辑是否和
TypeGuard标注的类型匹配,需要自行保证运行时逻辑和声明的缩窄类型一致,避免出现静态类型和实际运行类型不匹配的问题。 TypeGuard支持所有Python类型体系的缩窄,包括泛型、联合类型分支、自定义类、嵌套类型等所有复杂场景。
内容的提问来源于stack exchange,提问作者PhilMacKay
相关产品推荐
相关产品推荐

