如何为Python函数返回值标注实例而非类型以实现类型收窄?
如何标注函数返回单例实例以支持类型收窄?
你可以通过以下方式实现需求,无需额外TypeGuard代码,保留is语句的类型收窄能力:
一、字符串单例场景
先使用Final标记单例变量为不可变,再结合Literal标注返回类型,类型检查器会识别is判断并收窄类型:
from typing import Final, Literal, Union my_marker: Final[str] = "This is very singletony, I promise!" def get_object_or_a_singleton_marker() -> Union[int, Literal[my_marker]]: some_condition_is_met = False # 示例条件 if some_condition_is_met: return 123 # 示例int返回值 else: return my_marker a_var = get_object_or_a_singleton_marker() if a_var is not my_marker: # 此处a_var类型会被收窄为int reveal_type(a_var) # 类型检查器将显示:int else: # 此处a_var类型为Literal["This is very singletony, I promise!"] reveal_type(a_var)
二、类实例单例场景
同样用Final标记单例实例,返回类型直接声明为目标类型与单例类的联合,is判断会触发类型收窄:
from typing import Final, Union class SingletonMarker: # 实现单例逻辑 _instance = None def __new__(cls): if cls._instance is None: cls._instance = super().__new__(cls) return cls._instance my_marker: Final[SingletonMarker] = SingletonMarker() def get_obj_or_singleton() -> Union[int, SingletonMarker]: some_condition_is_met = False # 示例条件 if some_condition_is_met: return 456 else: return my_marker a_var = get_obj_or_singleton() if a_var is not my_marker: # 此处a_var类型收窄为int reveal_type(a_var) else: # 此处a_var类型为SingletonMarker(且是唯一实例) reveal_type(a_var)
关键说明
- 之前的写法无效是因为:直接用
my_marker作为类型表达式不符合语法;未标记Final时,Literal[my_marker]无法被识别为固定字面量;type[my_marker]返回的是实例的泛型类型(如str),而非特定实例,因此无法触发精确的类型收窄。 - 上述方案在主流类型检查器(如mypy、pyright)中均能正常工作,无需额外辅助函数。
内容的提问来源于stack exchange,提问作者Guillaume
相关产品推荐
相关产品推荐

