简介
Python 中的 inspect
模块提供了一些有用的函数帮助获取对象的信息,例如模块、类、方法、函数、堆栈追踪、帧对象以及代码对象. 比如, 它可以辅助检查类的内容, 获取某个方法的源码, 获取并格式化某个函数的参数列表, 或者获取堆栈追踪的详细信息.
inspect.signiture
inspect.signiture
inspect.Parameter
该方法可以获取函数的签名.
1
2
3
4
5
6
7
8
9
import inspect
def foo(a, *args, b: int=1, c=(2, 3), d="4", **kwargs):
pass
sig = inspect.signature(foo)
for n, p in sig.parameters.items():
print(type(p), p.name, p.kind, p.annotation, p.default)
输出结果为
1
2
3
4
5
6
<class 'inspect.Parameter'> a POSITIONAL_OR_KEYWORD <class 'inspect._empty'> <class 'inspect._empty'>
<class 'inspect.Parameter'> args VAR_POSITIONAL <class 'dict'> <class 'inspect._empty'>
<class 'inspect.Parameter'> b KEYWORD_ONLY <class 'int'> 1
<class 'inspect.Parameter'> c KEYWORD_ONLY <class 'inspect._empty'> (2, 3)
<class 'inspect.Parameter'> d KEYWORD_ONLY <class 'inspect._empty'> 4
<class 'inspect.Parameter'> kwargs VAR_KEYWORD <class 'inspect._empty'> <class 'inspect._empty'>
可以发现, inspect
模块把参数表示为 inspect.Parameter
的实例. 参数的 kind
表示参数类型, 共有五种:
POSITIONAL_OR_KEYWORD
: 表示该参数既可以是定位参数, 也可以是关键字参数VAR_POSITIONAL
: 多个位置参数, 通常是*args
VAR_KEYWORD
: 多个关键字参数, 通常是**kwargs
KEYWORD_ONLY
: 必须是关键字参数, 表示那些在*args
后面的参数, 必须通过关键字提供POSITIONAL_ONLY
: 必须是定位参数, 用户遇不到这种需求, python 的一些古老的内置函数包含这种类型的参数, 比如pow
.
下面的函数可以获取函数的所有参数(Ref). 该函数返回函数的 (1)所有参数名的列表, (2) 可变定位参数名, (3) 可变关键字参数名, (4) 定位参数名的列表, (5) 关键字参数的字典.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
def get_argspec(f):
sig = inspect.signature(f)
args = [n for n, p in sig.parameters.items() if p.kind in ARG_TYPES]
pos_args = [
n
for n, p in sig.parameters.items()
if p.kind in POSARG_TYPES and p.default == inspect._empty
]
varargs = [
n for n, p in sig.parameters.items() if p.kind == Parameter.VAR_POSITIONAL
]
# only use first vararg (how on earth would you have more anyways?)
vararg_name = varargs[0] if varargs else None
varkws = [n for n, p in sig.parameters.items() if p.kind == Parameter.VAR_KEYWORD]
# only use first varkw (how on earth would you have more anyways?)
kw_wildcard_name = varkws[0] if varkws else None
kwargs = OrderedDict(
[
(n, p.default)
for n, p in sig.parameters.items()
if p.default != inspect._empty
]
)
return args, vararg_name, kw_wildcard_name, pos_args, kwargs