You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python3.10运行时如何获取Optional包装的底层类型完成类型对比

解决方法

首先要明确:Python的类型注解默认只供静态类型检查工具识别,不会在运行时改变变量的实际类型,type()方法只能拿到变量当前绑定的实例的真实类型,根本读不到你写的Optional[str]注解信息,自然没法基于注解做类型对比。

要在运行时穿透Optional修饰符拿到它包裹的底层类型,用Python 3.10原生支持的typing.get_origin()和typing.get_args()两个方法就可以实现:

  • Optional[X]本质是Union[X, None](3.10中也等价于X | None写法)的语法糖
  • get_origin(注解对象)可以拿到泛型注解的原始根类型,用来识别当前注解是不是Optional对应的联合类型
  • get_args(注解对象)可以拿到泛型包裹的所有参数,排除None类型后剩下的就是Optional包装的底层类型

修正后的可运行代码如下,运行后会输出你预期的结果:

from typing import Optional, get_type_hints, get_args, get_origin
import types

my_string: str = ""
my_optional_string: Optional[str] = ""

def unwrap_optional(annotation):
    # 兼容typing.Union、3.10+ | 联合类型两种Optional的底层实现
    union_origins = (types.UnionType, type(Optional[str]))
    if get_origin(annotation) in union_origins:
        args = get_args(annotation)
        # 过滤掉None类型,剩下的就是Optional包裹的实际类型
        real_types = [arg for arg in args if arg is not type(None)]
        if len(real_types) == 1:
            return real_types[0]
    return annotation

# 拿到当前作用域的类型注解,类/函数场景传对应类/函数对象即可
hints = get_type_hints(__import__(__name__))
base_str_type = unwrap_optional(hints["my_string"])
unwrapped_optional_type = unwrap_optional(hints["my_optional_string"])

if base_str_type == unwrapped_optional_type:
    print("Yes they both can contain strings")
else:
    print("No, not stringy types")

补充说明:如果你不需要校验注解,只是要判断运行时传入的值是不是合法的字符串,直接用isinstance(变量, str)即可——Optional[str]允许的合法值只有字符串实例和None,非None值直接用isinstance判断类型就足够,不需要额外解析注解。

内容的提问来源于stack exchange,提问作者JimmyNJ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 12:39:15