如何为可返回指定默认值的Python函数正确标注类型
正确标注方案
你可以通过typing.overload装饰器声明不同入参对应的返回类型,让mypy精准识别不同调用场景的返回值类型:
from typing import Mapping, Optional, TypeVar, overload, Union # 定义default参数支持的类型范围 DT = TypeVar('DT', bound=Optional[str]) # 重载1:不传default参数时,返回Optional[str] @overload def get_something_from_data(data: Mapping[str, str]) -> Optional[str]: ... # 重载2:传入default参数时,返回 str 和 default类型的联合 # Python 3.10+ 可直接写为 -> str | DT @overload def get_something_from_data(data: Mapping[str, str], default: DT) -> Union[str, DT]: ... # 实际函数实现 def get_something_from_data(data: Mapping[str, str], default: Optional[str] = None) -> Optional[str]: """Get something out of `data` if it is there, if not return the value of `default`. If `default` is not provided, return None. """ # 这里补充你的实际业务逻辑即可 if "target_key" in data: return data["target_key"] return default
效果验证
- 场景1:传入字符串类型的default
mypy会推断has_value = get_something_from_data(data, "fallback") return has_value.endswith("k")has_value为str类型,不会报错。 - 场景2:不传入default参数
mypy会直接抛出错误提示:has_value = get_something_from_data(data) return has_value.endswith("k")Item "None" of "Optional[str]" has no attribute "endswith",符合预期的风险校验要求。
原写法问题说明
你之前使用的单TypeVar标注没有明确区分「不传default」的调用场景,mypy没有正确将该场景下的返回值推断为Optional[str],导致空风险漏检。而重载写法可以精准匹配不同的调用签名,完全覆盖你的校验需求。
内容的提问来源于stack exchange,提问作者shevron
相关产品推荐
相关产品推荐

