对象注解#
限制: Python 3.10 及其以上版本
inspect 用于对象检查#
inspect
模块支持:类型检查、获取源代码、检查类与函数、检查解释器的调用堆栈。
签名与形参#
inspect.Signature(parameters=None, *, return_annotation=Signature.empty)
代表了一个函数的整体签名。它为每个被函数接受的参数存储一个Parameter
对象。可以使用辅助函数inspect.signature(obj)()
获取对象obj
的签名。可选的
parameters
实参是一个Parameter
对象的序列,它被验证以检查是否有名称重复的形参,以及形参的顺序是否正确,即先是仅有位置的形参,然后是有位置或关键字的形参,以及有默认值的形参紧随没有默认值的形参。可选的
return_annotation
实参,可以是一个任意的 Python 对象,是可调用对象的 “return” 注解。
inspect.Parameter(name, kind, *, default=Parameter.empty, annotation=Parameter.empty)
代表函数签名中的一个参数。
备注
看一个例子:
from inspect import signature
def foo(a, *, b:int, **kwargs):
...
# 获取 `foo` 的签名
sig = signature(foo)
sig
<Signature (a, *, b: int, **kwargs)>
str(sig) # 转换为字符串
'(a, *, b: int, **kwargs)'
sig.parameters # 形参名称与相应的 Parameter 对象的有序映射。
mappingproxy({'a': <Parameter "a">,
'b': <Parameter "b: int">,
'kwargs': <Parameter "**kwargs">})
sig.parameters['b'] # 获取给定名称的参数
<Parameter "b: int">
sig.parameters['b'].annotation # 获取参数的注解
int
# 创建新的签名
new_sig = sig.replace(return_annotation="new return anno")
str(new_sig)
"(a, *, b: int, **kwargs) -> 'new return anno'"
from inspect import Parameter
# 创建参数实例
param = Parameter('foo', Parameter.KEYWORD_ONLY, default=42)
str(param)
'foo=42'
str(param.replace()) # param 的浅拷贝
'foo=42'
# 添加注解
str(param.replace(default=Parameter.empty, annotation='spam'))
"foo: 'spam'"
参数传值:
def foo(a, b='ham', *args): ...
ba = signature(foo).bind('spam')
str(ba)
"<BoundArguments (a='spam')>"
ba.arguments # 查看实参
{'a': 'spam'}
ba.apply_defaults() # 应用默认值
ba.arguments # 查看实参
{'a': 'spam', 'b': 'ham', 'args': ()}
注解#
inspect.get_annotations(obj, *, globals=None, locals=None, eval_str=False)()
计算一个对象的注解 dict。
obj
可以是一个 callable,类,或模块。传入任何其他类型的对象会引发 TypeError
。
inspect.get_annotations()
每次调用都会返回一个新的 dict;对同一个对象调用两次会返回两个不同但等价的 dict。
对象注解属性的最佳实践:
Python 3.10 以上版本的最佳做法:使用三个参数去调用 getattr()
,比如 getattr(o, '__annotations__', None)
。