能否在被调用函数中实现类型检查?Pyright类型校验疑问
解决Pyright无法识别辅助函数类型收缩的问题
要让Pyright识别你的is_employee过滤函数后的类型变化,需要使用**类型守卫(Type Guard)**注解,明确告诉类型检查器:当函数返回True时,输入的Personnel实例的employee属性已确定为非None的Employee类型。
具体实现步骤
导入TypeGuard
- Python 3.10+ 可直接从
typing模块导入; - Python 3.9及以下需先安装
typing_extensions包,再从该包导入。
- Python 3.10+ 可直接从
定义类型守卫函数
你可以通过两种方式实现:
方式1:使用Protocol(更清晰的类型约束)
from dataclasses import dataclass from typing import Optional, TypeGuard, Protocol # 补充示例中缺失的基础类 @dataclass class Person: pass @dataclass class Job: pass @dataclass() class Personnel: person: Person employee: Optional[Employee] @dataclass() class Employee: department: str jobs: list[Job] # 定义协议,标识拥有非None employee的Personnel class HasEmployee(Protocol): employee: Employee # 类型守卫函数:返回True时,输入符合HasEmployee协议 def is_employee(x: Personnel) -> TypeGuard[HasEmployee]: return x.employee is not None
方式2:直接收缩属性类型(更简洁)
如果不需要额外定义协议,也可以让Pyright自动推导类型收缩:
from typing import TypeGuard def is_employee(x: Personnel) -> TypeGuard[Personnel]: return x.employee is not None
- 使用过滤函数
此时在列表推导式中使用is_employee过滤后,Pyright会自动识别personnel.employee已为Employee类型,不再报错:
all_jobs = [ job for personnel in all_personnel_list if is_employee(personnel) for job in personnel.employee.jobs ]
原理说明
TypeGuard是类型检查器(如Pyright)识别类型收缩的标记,它告诉检查器:当函数返回True时,输入参数的类型满足注解中指定的约束。这样,在过滤后的代码块中,类型检查器会自动应用收缩后的类型,避免不必要的None检查提示。
内容的提问来源于stack exchange,提问作者Beaudry Chase
相关产品推荐
相关产品推荐

