文章目录
- inspect模块主要提供了四种用处
- 小结
- inspect模块类
- 获取对象信息
inspect模块主要提供了四种用处
1、对是否是模块,框架,函数等进行类型检查。
2、获取源码
3、获取类或函数的参数的信息
4、解析堆栈
# -*-coding:UTF-8 -*-
import inspect
def a(a, b=0, *c, d, e=1, **f):
pass
aa = inspect.signature(a)
print("inspect.signature(fn)是:%s" % aa)
print("inspect.signature(fn)的类型:%s" % (type(aa)))
print("\n")
bb = aa.parameters
print("signature.paramerters属性是:%s" % bb)
print("ignature.paramerters属性的类型是%s" % type(bb))
print("\n")
for cc, dd in bb.items():
print("mappingproxy.items()返回的两个值分别是:%s和%s" % (cc, dd))
print("mappingproxy.items()返回的两个值的类型分别是:%s和%s" % (type(cc), type(dd)))
print("\n")
ee = dd.kind
print("Parameter.kind属性是:%s" % ee)
print("Parameter.kind属性的类型是:%s" % type(ee))
print("\n")
gg = dd.default
print("Parameter.default的值是: %s" % gg)
print("Parameter.default的属性是: %s" % type(gg))
print("\n")
ff = inspect.Parameter.KEYWORD_ONLY
print("inspect.Parameter.KEYWORD_ONLY的值是:%s" % ff)
print("inspect.Parameter.KEYWORD_ONLY的类型是:%s" % type(ff))
运行结果:
inspect.signature(fn)是:(a, b=0, *c, d, e=1, **f)
inspect.signature(fn)的类型:<class 'inspect.Signature'>
signature.paramerters属性是:OrderedDict([('a', <Parameter "a">), ('b', <Parameter "b=0">), ('c', <Parameter "*c">), ('d', <Parameter "d">), ('e', <Parameter "e=1">), ('f', <Parameter "**f">)])
ignature.paramerters属性的类型是<class 'mappingproxy'>
mappingproxy.items()返回的两个值分别是:a和a
mappingproxy.items()返回的两个值的类型分别是:<class 'str'>和<class 'inspect.Parameter'>
Parameter.kind属性是:POSITIONAL_OR_KEYWORD
Parameter.kind属性的类型是:<enum '_ParameterKind'>
Parameter.default的值是: <class 'inspect._empty'>
Parameter.default的属性是: <class 'type'>
mappingproxy.items()返回的两个值分别是:b和b=0
mappingproxy.items()返回的两个值的类型分别是:<class 'str'>和<class 'inspect.Parameter'>
Parameter.kind属性是:POSITIONAL_OR_KEYWORD
Parameter.kind属性的类型是:<enum '_ParameterKind'>
Parameter.default的值是: 0
Parameter.default的属性是: <class 'int'>
mappingproxy.items()返回的两个值分别是:c和*c
mappingproxy.items()返回的两个值的类型分别是:<class 'str'>和<class 'inspect.Parameter'>
Parameter.kind属性是:VAR_POSITIONAL
Parameter.kind属性的类型是:<enum '_ParameterKind'>
Parameter.default的值是: <class 'inspect._empty'>
Parameter.default的属性是: <class 'type'>
mappingproxy.items()返回的两个值分别是:d和d
mappingproxy.items()返回的两个值的类型分别是:<class 'str'>和<class 'inspect.Parameter'>
Parameter.kind属性是:KEYWORD_ONLY
Parameter.kind属性的类型是:<enum '_ParameterKind'>
Parameter.default的值是: <class 'inspect._empty'>
Parameter.default的属性是: <class 'type'>
mappingproxy.items()返回的两个值分别是:e和e=1
mappingproxy.items()返回的两个值的类型分别是:<class 'str'>和<class 'inspect.Parameter'>
Parameter.kind属性是:KEYWORD_ONLY
Parameter.kind属性的类型是:<enum '_ParameterKind'>
Parameter.default的值是: 1
Parameter.default的属性是: <class 'int'>
mappingproxy.items()返回的两个值分别是:f和**f
mappingproxy.items()返回的两个值的类型分别是:<class 'str'>和<class 'inspect.Parameter'>
Parameter.kind属性是:VAR_KEYWORD
Parameter.kind属性的类型是:<enum '_ParameterKind'>
Parameter.default的值是: <class 'inspect._empty'>
Parameter.default的属性是: <class 'type'>
inspect.Parameter.KEYWORD_ONLY的值是:KEYWORD_ONLY
inspect.Parameter.KEYWORD_ONLY的类型是:<enum '_ParameterKind'>
小结
inspect.signature(fn)
将返回一个inspect.Signature
类型的对象,值为fn这个函数的所有参数
inspect.Signature
对象的paramerters
属性是一个mappingproxy
(映射)类型的对象,值为一个有序字典(Orderdict)。
这个字典里的key是即为参数名,str
类型
这个字典里的value是一个inspect.Parameter
类型的对象,根据我的理解,这个对象里包含的一个参数的各种信息
inspect.Parameter
对象的kind属性是一个_ParameterKind
枚举类型的对象,值为这个参数的类型(可变参数,关键词参数,etc)
inspect.Parameter
对象的default
属性:如果这个参数有默认值,即返回这个默认值,如果没有,返回一个inspect._empty
类。
inspect模块类
inspect.ArgInfo inspect.getmoduleinfo
inspect.ArgSpec inspect.getmodulename
inspect.Arguments inspect.getmro
inspect.Attribute inspect.getouterframes
inspect.BlockFinder inspect.getsource
inspect.CO_GENERATOR inspect.getsourcefile
inspect.CO_NESTED inspect.getsourcelines
inspect.CO_NEWLOCALS inspect.imp
inspect.CO_NOFREE inspect.indentsize
inspect.CO_OPTIMIZED inspect.isabstract
inspect.CO_VARARGS inspect.isbuiltin
inspect.CO_VARKEYWORDS inspect.isclass
inspect.EndOfBlock inspect.iscode
inspect.ModuleInfo inspect.isdatadescriptor
inspect.TPFLAGS_IS_ABSTRACT inspect.isframe
inspect.Traceback inspect.isfunction
inspect.attrgetter inspect.isgenerator
inspect.classify_class_attrs inspect.isgeneratorfunction
inspect.cleandoc inspect.isgetsetdescriptor
inspect.currentframe inspect.ismemberdescriptor
inspect.dis inspect.ismethod
inspect.findsource inspect.ismethoddescriptor
inspect.formatargspec inspect.ismodule
inspect.formatargvalues inspect.isroutine
inspect.getabsfile inspect.istraceback
inspect.getargs inspect.joinseq
inspect.getargspec inspect.linecache
inspect.getargvalues inspect.modulesbyfile
inspect.getblock inspect.namedtuple
inspect.getcallargs inspect.os
inspect.getclasstree inspect.re
inspect.getcomments inspect.stack
inspect.getdoc inspect.string
inspect.getfile inspect.strseq
inspect.getframeinfo inspect.sys
inspect.getinnerframes inspect.tokenize
inspect.getlineno inspect.trace
inspect.getmembers inspect.types
inspect.getmodule inspect.walktree
其中,isxxx之类的就是检查对象是否为xxx的函数吧
例如 检查this是否是一个模块
In [16]: inspect.ismodule(this)
Out[16]: True
getxxx之类的就是获取对象的xxx属性,例如
In [17]: inspect.getmodule(this)
Out[17]: <module 'this' from '/usr/lib/python2.7/this.pyc'>
- 实例
# 判断模块、框架、类、函数的方法,和type返回的类型是一样的,只是这里是判断
inspect.getmodulename(path) 获取模块名称
inspect.ismodule(object) 是不是个模块
inspect.isclass(object) 是不是个类
inspect.ismethod(object) 是不是一个方法
inspect.isfunction(object) 是不是一个函数
inspect.isgeneratorfunction(object) 是不是一个生成器函数
inspect.isgenerator(object) 是不是一个生成器
inspect.iscoroutinefunction(object) 是不是一个协程函数
inspect.getsource(object) 获取对象的源码(并不会解析装饰器原码)
inspect.getsourcelines(object) 代码块,每行一个元素,组成数组
# signature 类 函数的签名信息:它包含了了函数的函数名、它的参数类型,它所在的类和名称空间及其他信息
# signature.parameters 里面存放的是函数的参数注解和返回值注解,组成的有序字典
# 参数注解常用的方法有:
empty 等同于inspect._empty表示一个参数没有被类型注释
name 参数的名称
default 参数的默认值,如果一个参数没有默认值,这个属性的值为inspect.empty
annotation 参数的注解类型,如果参数没有定义注解,这个属性的值为inspect.empty
kind 参数的类型
# 参数类型
_POSITIONAL_ONLY = _ParameterKind.POSITIONAL_ONLY # 位置参数_only
_POSITIONAL_OR_KEYWORD = _ParameterKind.POSITIONAL_OR_KEYWORD # 位置或关键字参数
_VAR_POSITIONAL = _ParameterKind.VAR_POSITIONAL # 可变位置参数
_KEYWORD_ONLY = _ParameterKind.KEYWORD_ONLY # keyword-only参数
_VAR_KEYWORD = _ParameterKind.VAR_KEYWORD # 可变关键字参数
# 获取对象的参数签名
>>> import inspect
>>> def add(x:int,y:int):
... return x+y
>>> sig = inspect.signature(add)
>>> params = sig.parameters
>>> print(params)
OrderedDict([('x', <Parameter "x:int">), ('y', <Parameter "y:int">)])
>>> params['x'].annotation
<class 'int'> # 如果没有定义x的参数注解,那么这里就是inspect._empty
# 案例检查参数
import inspect
import functools
def check(fn): # 这个装饰器只能用于函数,不能用于类方法
@functools.wraps(fn)
def warpper(*args, **kwargs):
sig = inspect.signature(fn) # 获取fn的参数
params = sig.parameters # 有序字典,OrderedDict([('x', <Parameter "x:int">), ('y', <Parameter "y:int">)])
values = list(params.values())
for i,j in enumerate(args):
if values[i].annotation != inspect._empty and not isinstance(j, values[i].annotation):
raise TypeError("you must input {}".format(values[i].annotation))
for k,v in kwargs.items():
if params[k].annotation != inspect._empty and not not isinstance(v,params[k].annotation):
raise TypeError("you must input {}".format(params[k].annotation))
return fn(*args, **kwargs)
return warpper
@check
def add(x:int,y:int):
return x+y
print(add(1,2))
# --------------------------获取函数的名字-------------------------------
def debug():
import inspect
caller_name = inspect.stack()[1][3]
print("[DEBUG]: enter {}()".format(caller_name))
def say_hello():
debug()
print("hello!")
say_hello()
# 结果:
[DEBUG]: enter say_hello()
hello!
获取对象信息
- getmembers(object[, predicate]):
这个方法是dir()的扩展版,它会将dir()找到的名字对应的属性一并返回,形如[(name, value), …]。另外,predicate是一个方法的引用,如果指定,则应当接受value作为参数并返回一个布尔值,如果为False,相应的属性将不会返回。使用is*作为第二个参数可以过滤出指定类型的属性。 - getmodule(object):
还在为第2节中的__module__
属性只返回字符串而遗憾吗?这个方法一定可以满足你,它返回object的定义所在的模块对象。 - get{file|sourcefile}(object):
获取object的定义所在的模块的文件名|源代码文件名(如果没有则返回None)。用于内建的对象(内建模块、类、函数、方法)上时会抛出TypeError异常。 - get{source|sourcelines}(object):
获取object的定义的源代码,以字符串|字符串列表返回。代码无法访问时会抛出IOError异常。只能用于module/class/function/method/code/frame/traceack对象。 - getargspec(func):
仅用于方法,获取方法声明的参数,返回元组,分别是(普通参数名的列表, *参数名, **参数名, 默认值元组)。如果没有值,将是空列表和3个None。如果是2.6以上版本,将返回一个命名元组(Named Tuple),即除了索引外还可以使用属性名访问元组中的元素。 - getargvalues(frame):
仅用于栈帧,获取栈帧中保存的该次函数调用的参数值,返回元组,分别是(普通参数名的列表, *参数名, **参数名, 帧的locals())。如果是2.6以上版本,将返回一个命名元组(Named Tuple),即除了索引外还可以使用属性名访问元组中的元素。 - getcallargs(func[, *args][, **kwds]):
返回使用args和kwds调用该方法时各参数对应的值的字典。这个方法仅在2.7版本中才有。 - getmro(cls):
返回一个类型元组,查找类属性时按照这个元组中的顺序。如果是新式类,与cls.__mro__
结果一样。但旧式类没有__mro__
这个属性,直接使用这个属性会报异常,所以这个方法还是有它的价值的。 返回当前的栈帧对象。