python 3.10+ 中应使用 inspect.get_annotations() 安全读取注解,它自动解析字符串化注解、适配新语义、避免 attributeerror;该接口只读,不参与静态类型检查,mypy/pyright 均基于源码 ast 而非运行时注解工作。

<strong>annotations</strong> 在 Python 3.10+ 中行为已变更,直接访问不再安全
Python 3.10 起,<strong>annotations</strong> 的语义发生了实质性变化:类不再继承父类的注解,子类的 <strong>annotations</strong> 默认为空字典;函数和模块虽仍可用,但对 functools.partial 等可调用对象,<strong>annotations</strong> 可能根本不存在。硬编码访问 obj.<strong>annotations</strong> 容易触发 AttributeError 或返回错误内容,尤其在反射、序列化、API 文档生成等场景下极易出错。
推荐统一使用 inspect.get_annotations() 替代手动访问:
- 它自动处理字符串化注解(如
"list[str]")的解析,无需手动eval或typing.ForwardRef - 对任意对象(函数、类、模块、
partial、甚至带__annotations__的自定义类)都返回安全结果 - 内部已适配 3.10+ 的新规则,比如跳过继承链、区分类与实例注解
示例对比:
# ❌ 危险写法(3.10+ 不可靠)
def get_ann(obj):
return obj.__annotations__ # 可能在 partial 或空子类上失败
<h1>✅ 推荐写法</h1><p>import inspect
def get_ann(obj):
return inspect.get_annotations(obj) # 始终返回 dict,无异常
</p>
inspect.get_annotations() 不支持运行时动态修改注解
inspect.get_annotations() 是只读接口,它不提供写入能力,也不参与类型检查流程本身。它的作用仅限于「安全读取」——这恰恰是设计意图:把注解当作声明式元数据,而非运行时可变状态。如果你试图在运行中动态 patch <strong>annotations</strong> 来影响 mypy 或 IDE 行为,基本无效;mypy 在静态分析阶段已固化 AST 中的注解节点,而 IDE 通常缓存或预解析注解。
图片提示词生成器?不止如此。 马甲系统 —— 把脑海中的画面,翻译成AI能理解的专业表达。 用得越多,它越懂你:首次需要多问几句确认方向,用久了几乎一说就懂。 用得越多,它越快:缓存机制让后续对话越来越省。 RAG进化:成功案例持续入库,越跑越聪明。 输入「新手指南」查看完整功能介绍
常见误用场景包括:
- 在装饰器里给函数动态加
__annotations__,期望 IDE 补全生效 → 实际不触发重分析 - 用
setattr(func, '__annotations__', {...})模拟泛型参数 → mypy 无视,且可能破坏inspect.signature() - 在测试中临时覆盖类注解做 mock → 3.10+ 下子类注解为空,mock 失效
mypy 和 pyright 的检查逻辑完全脱离运行时注解值
静态类型检查器(如 mypy)不读取 <strong>annotations</strong> 或 inspect.get_annotations() 的运行时返回值。它们直接解析源码 AST,在语法树层面提取字面量注解(包括字符串形式)。这意味着:
- 你在代码里写
name: "User"(字符串前向引用),mypy能正确解析;但若运行时通过setattr注入相同字符串,它完全看不到 -
mypy --strict的报错位置、错误类型、是否启用disallow_untyped_defs等,全部由配置和源码决定,与运行时对象状态无关 - 所谓“分离管理”,本质是承认:类型系统属于编译期契约,不是运行期配置
真正需要动态类型逻辑的地方,应该用 TypedDict、Literal、Protocol 或 Pydantic 模型,而不是绕过注解机制去 hack 运行时字典。
复杂点在于,很多人混淆了「类型提示的存储位置」和「类型检查的执行时机」。前者是源码/AST/注解字典,后者是独立工具链。一旦混用,比如在运行时改注解再调 mypy,就会发现什么也没变——因为 mypy 根本没看那个字典。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










