Python inspect获取参数注解 导入与内定义返回结果不一致问题
成因
直接读取inspect.Parameter.annotation返回的是函数__annotations__属性存储的原始值,不会触发自动解析,两种场景结果存在差异是Python针对不同运行环境设计的注解默认存储规则导致的:
- 交互式Shell(REPL)中定义函数时,解释器会立即对类型注解求值,直接将实际类型对象存入
__annotations__,因此读取时直接返回<class 'str'>类对象。 - 从外部
.py文件导入函数时,出于提升模块加载速度、支持前向引用(注解引用后续才定义的类/类型)的考虑,Python默认不会在导入阶段求值注解,而是将注解对应的源码片段以字符串形式存入__annotations__,直接读取时就会得到'str'这类字符串值。
如果代码中显式写了from __future__ import annotations,无论函数在哪个环境定义,注解都会统一以字符串形式存储,直接读取都会返回字符串。
解决方案
不要直接读取inspect.Parameter.annotation的原始值,用以下两种任意一种方式都能拿到一致的实际类型对象:
- 使用标准库
typing.get_type_hints()方法解析注解,该方法兼容所有Python 3.5+版本,会自动处理字符串注解、前向引用,不受函数定义来源影响:
from typing import get_type_hints # 无论函数定义在交互环境还是外部文件,返回结果一致 hints = get_type_hints(accepts_string) s_type = hints['s'] # 固定为<class 'str'>
- Python 3.10及以上版本可以在调用
inspect.signature()时传入eval_str=True参数,触发签名自动解析字符串形式的注解:
import inspect sig = inspect.signature(accepts_string, eval_str=True) s_type = sig.parameters['s'].annotation # 固定为<class 'str'>
内容的提问来源于stack exchange,提问作者Peter Wensel
相关产品推荐
相关产品推荐

