inspect 模块主要用来

  1. type checking
  2. getting source code
  3. inspecting classes and functions
  4. examining the interpreter stack

常用函数
isxxx() 判断是不是某个类别
eg.
ismodule isclass ismethod isfunction ...

getxxx() 获取信息
eg.

getmembers(obj[,predicate]) 获取obj的所有成员,perdicate可以用来传入一个func来过滤 比如getmembers(obj,isfunction) 获取obj的所有函数
getfile(obj) 获取obj定义的文件
getsource(obj) 获取obj定义的源码
getargspec(callable_obj) 即将弃用,专用signature(),获取一个可调用obj的参数信息,不支持指定的kw参数(def t(*,g=1))
getfullargspec(callable_obj) 获取一个可调用obj的参数信息,支持指定的kw参数

signature(callable_obj,*,follow_wrapped=True) 这个在python3.3新引入的函数,会返回一个Signature对象,如果是实例方法不会返回self,但是getfullargspec会:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class T:
def __init__(self):
pass

def ttt(self,a,b=1,*args,g=1,**kw):
pass

t = T()
print(inspect.getfullargspec(T.ttt))
print(inspect.signature(T.ttt))
print(inspect.getfullargspec(t.ttt))
print(inspect.signature(t.ttt))
###
FullArgSpec(args=['self', 'a', 'b'], varargs='args', varkw='kw', defaults=(1,), kwonlyargs=['g'], kwonlydefaults={'g': 1}, annotations={})
(self, a, b=1, *args, g=1, **kw)
FullArgSpec(args=['self', 'a', 'b'], varargs='args', varkw='kw', defaults=(1,), kwonlyargs=['g'], kwonlydefaults={'g': 1}, annotations={})
(a, b=1, *args, g=1, **kw)

一个校验器:

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
27
import inspect


def typeassert(*ty_args, **ty_kargs):
def decorator(func):
sig = inspect.signature(func)
btypes = sig.bind_partial(*ty_args, **ty_kargs).arguments

def wrapper(*args, **kargs):
for name, obj in sig.bind(*args, **kargs).arguments.items():
if name in btypes:
if not isinstance(obj, btypes[name]):
raise TypeError('"%s" must be "%s"' % (name, btypes[name]))

return func(*args, **kargs)

return wrapper

return decorator


@typeassert(int, str, list)
def f(a, b, c):
print(a, b, c)


f(1, 1, [])