1、简述
获取函数签名对象。
函数签名包含了一个函数的信息,包括函数名、它的参数类型、它所在的类和名称空间及其他信息)。
2、基本用法
inspect模块主要提供了四种用处:
1.对是否是模块、框架、函数进行类型检查
2.获取源码
3.获取类或者函数的参数信息
4.解析堆栈
2.1 对是否是模块、框架、函数进行类型检查
inspect.getmembers
getmembers的实现步骤
获取 object 的所有成员的名字,包含 object 的父类的成员,存入 names 列表
从 object 的基类中获取 DynamicClassAttribute 类型的成员,添加到 names 列表中
遍历 names 列表,通过 getattr 方法获取 object 中所有属性的值,getattr(x, ‘y’) 相当于 x.y
用 predicate 判断成员值,把通过判断的成员,以(成员名, 成员值)的形式添加到 results 这个列表中
对 results 列表按 成员名 进行排序
inspect.getmembers(object[, predicate])
- 1
第二个参数通常可以根据需要调用如下16个方法;
返回值为object的所有成员,以(name,value)对组成的列表
inspect.ismodule(object): 是否为模块 inspect.isclass(object):是否为类 inspect.ismethod(object):是否为方法(bound method written in python) inspect.isfunction(object):是否为函数(python function, including lambda expression) inspect.isgeneratorfunction(object):是否为python生成器函数 inspect.isgenerator(object):是否为生成器 inspect.istraceback(object): 是否为traceback inspect.isframe(object):是否为frame inspect.iscode(object):是否为code inspect.isbuiltin(object):是否为built-in函数或built-in方法 inspect.isroutine(object):是否为用户自定义或者built-in函数或方法 inspect.isabstract(object):是否为抽象基类 inspect.ismethoddescriptor(object):是否为方法标识符 inspect.isdatadescriptor(object):是否为数字标识符,数字标识符有__get__ 和__set__属性; 通常也有__name__和__doc__属性 inspect.isgetsetdescriptor(object):是否为getset descriptor inspect.ismemberdescriptor(object):是否为member descriptor
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
inspect的getmembers()方法可以获取对象(module、class、method等)的如下属性:
| Attribute | Type | Description | Notes |
|---|---|---|---|
__doc__ | module | documentation string 文档字符串 | |
__file__ | filename (missing for built-in modules) 文件名(内置模块没有文件名) | ||
__doc__ | class | documentation string 文档字符串 | |
__module__ | name of module in which this class was defined 该类型被定义时所在的模块的名称 | ||
__doc__ | method | documentation string 文档字符串 | |
__name__ | name with which this method was defined 该方法定义时所使用的名称 | ||
im_class | class object that asked for this method | (1) | |
im_func or __func__ | function object containing implementation of method 实现该方法的函数对象 | ||
im_self or __self__ | instance to which this method is bound, or None 该方法被绑定的实例,若没有绑定则为 None | ||
__doc__ | function | documentation string 文档字符串 | |
__name__ | name with which this function was defined 用于定义此函数的名称 | ||
func_code | code object containing compiled function bytecode 包含已编译函数的代码对象 | ||
func_defaults | tuple of any default values for arguments | ||
func_doc | (same as __doc__) | ||
func_globals | global namespace in which this function was defined | ||
func_name | (same as __name__) | ||
__iter__ | generator | defined to support iteration over container | |
close | raises new GeneratorExit exception inside the generator to terminate the iteration | ||
gi_code | code object | ||
gi_frame | frame object or possibly None once the generator has been exhausted | ||
gi_running | set to 1 when generator is executing, 0 otherwise | ||
next | return the next item from the container | ||
send | resumes the generator and “sends” a value that becomes the result of the current yield-expression | ||
throw | used to raise an exception inside the generator | ||
tb_frame | traceback | frame object at this level 此级别的框架对象 | |
tb_lasti | index of last attempted instruction in bytecode | ||
tb_lineno | current line number in Python source code | ||
tb_next | next inner traceback object (called by this level) | ||
f_back | frame | next outer frame object (this frame’s caller) | |
f_builtins | builtins namespace seen by this frame | ||
f_code | code object being executed in this frame | ||
f_exc_traceback | traceback if raised in this frame, or None | ||
f_exc_type | exception type if raised in this frame, or None | ||
f_exc_value | exception value if raised in this frame, or None | ||
f_globals | global namespace seen by this frame | ||
f_lasti | index of last attempted instruction in bytecode | ||
f_lineno | current line number in Python source code | ||
f_locals | local namespace seen by this frame | ||
f_restricted | 0 or 1 if frame is in restricted execution mode | ||
f_trace | tracing function for this frame, or None | ||
co_argcount | code | number of arguments (not including * or ** args) | |
co_code | string of raw compiled bytecode 原始编译字节码的字符串 | ||
co_consts | tuple of constants used in the bytecode 字节码中使用的常量元组 | ||
co_filename | name of file in which this code object was created 创建此代码对象的文件的名称 | ||
co_firstlineno | number of first line in Python source code | ||
co_flags | bitmap: 1=optimized | 2=newlocals | 4=*arg |8=**arg | ||
co_lnotab | encoded mapping of line numbers to bytecode indices 编码的行号到字节码索引的映射 | ||
co_name | name with which this code object was defined 定义此代码对象的名称 | ||
co_names | tuple of names of local variables 局部变量名称的元组 | ||
co_nlocals | number of local variables 局部变量的数量 | ||
co_stacksize | virtual machine stack space required 需要虚拟机堆栈空间 | ||
co_varnames | tuple of names of arguments and local variables 参数名和局部变量的元组 | ||
__doc__ | builtin | documentation string 文档字符串 | |
__name__ | original name of this function or method 此函数或方法的原始名称 | ||
__self__ | instance to which a method is bound, or None |
例子:
import inspect
# 待获取签名的函数
def func(x:int, y:str, z:list) -> None:
'''
weiwei
'''
pass
# return signature类型的对象,值为函数的所有参数
print(inspect.signature(func))
# return orderdict key就是参数名 str类型
print(inspect.signature(func).parameters)
# return module的所有成员的name和obj类型
print(inspect.getmembers(func))
# 返回document
print(inspect.getdoc(func))
print(inspect.isfunction(func)) # 是否是函数
print(inspect.ismethod(func)) # 是否是类的方法
print(inspect.isgenerator(func)) # 是否是生成器对象
print(inspect.isgeneratorfunction(func))# 是否是生成器函数
print(inspect.isclass(func)) # 是否是类
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
![]()
2.2 获取源码
inspect.getdoc(object)# 获取object的documentation信息
inspect.getcomments(object)
inspect.getfile(object)# 返回对象的文件名
inspect.getmodule(object)# 返回object所属的模块名
inspect.getsourcefile(object)# 返回object的python源文件名;object不能使built-in的module, class, mothod
inspect.getsourcelines(object)# 返回object的python源文件代码的内容,行号+代码行
inspect.getsource(object)# 以string形式返回object的源代码
inspect.cleandoc(doc)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
2.3 获取类或者函数的参数信息
inspect.getclasstree(classes[, unique])
inspect.getargspec(func)
inspect.getargvalues(frame)
inspect.formatargspec(args[, varargs, varkw, defaults, formatarg, formatvarargs, formatvarkw, formatvalue, join])
inspect.formatargvalues(args[, varargs, varkw, locals, formatarg, formatvarargs, formatvarkw, formatvalue, join])
inspect.getmro(cls)#元组形式返回cls类的基类(包括cls类),以method resolution顺序;通常cls类为元素的第一个元素
inspect.getcallargs(func[, *args][, **kwds])#将args和kwds参数到绑定到为func的参数名;对bound方法,也绑定第一个参数(通常为self)到相应的实例;返回字典,对应参数名及其值;
- 1
- 2
- 3
- 4
- 5
- 6
- 7
例子:
>>> from inspect import getcallargs
>>> def f(a, b=1, *pos, **named):
... pass
>>> getcallargs(f, 1, 2, 3)
{'a': 1, 'named': {}, 'b': 2, 'pos': (3,)}
>>> getcallargs(f, a=2, x=4)
{'a': 2, 'named': {'x': 4}, 'b': 1, 'pos': ()}
>>> getcallargs(f)
Traceback (most recent call last):
...
TypeError: f() takes at least 1 argument (0 given)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
2.4 解析堆栈
inspect.getframeinfo(frame[, context])
inspect.getouterframes(frame[, context])
inspect.getinnerframes(traceback[, context])
inspect.currentframe()
inspect.stack([context])
inspect.trace([context])
- 1
- 2
- 3
- 4
- 5
- 6
3、使用实例一:获取一些常用监控信息
Parameter对象:保存在元组中,是只读的 ; name,参数的名字 ; annotation,参数的注解,可能没有定义 ;default,参数的缺省值,可能没有定义 ;empty,特殊的类,用来标记default属性或者注释annotation属性的空值 ; kind,实参如何绑定到形参,就是形参的类型
import inspect
# 待获取签名的函数
def func(x:int, y:str, z:list) -> None:
pass
# 获取签名对象,包括函数名,参数等
sig = inspect.signature(func)
print(type(sig))
print(sig)
# 获取签名中的参数,返回有序字典
params = sig.parameters
print(params)
# 通过循环并解构
for k, v in enumerate(params.items()):
name, param = v
print(param.annotation, param.kind, param.name)
# 获取签名中的返回值类型
ret = sig.return_annotation
print(ret)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
![]()
4、使用实例二:修饰器检测示例
检查用户输入是否符合参数注解的要求?
思路:调用时,判断用户输入的实参是否符合要求,用户感觉上还是在调用原函数,对用户输入的数据和声明的类型进行对比,如果不符合,提示用户。
import datetime, time
import inspect
def check_str(func):
def wrapper(*args, **kwargs):
obj = inspect.signature(func)
params = obj.parameters
for k, v in enumerate(params.items()):
name, param = v
for i in args:
if not isinstance(i, param.annotation):
print("{}: {} is not string".format(name, i))
raise TypeError
ret = func(*args, **kwargs)
return ret
return wrapper
@check_str
def str_add(str1:str, str2:str):
new_str = str1 + str2
print(new_str)
str_add("3", "4")
str_add(3, 4)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
![]()
5、实例三:常用代码模块
5.1 获取该模块的所有类
import inspect
for name, obj in inspect.getmembers(unittest):
"""获取该模块的所有类"""
if inspect.isclass(obj):
print(obj.__name__)
- 1
- 2
- 3
- 4
- 5
- 6
举例:
import inspect for name, obj in inspect.getmembers(inspect): """获取该模块的所有类""" if inspect.isclass(obj): print(obj.__name__)
- 1
- 2
- 3
- 4
- 5
- 6
5.2 获取某个类中的函数
举例
import inspect class classtest(): def __init__(self): '''哈哈哈''' a = 100 def add(self): '''加法''' return self.a + 100 """下面可以写出带序号的方法""" driver = [] print(classtest.__init__.__doc__) for i in inspect.getmembers(classtest):#获取Page类中的所有成员方法,i返回的是一个元祖,第一个元素是方法名,第二个是内存地址 if inspect.isfunction(i[1]):#判断成员是不是一个函数方法 driver.append(i[1].__doc__)#是打印他的doc for i in enumerate(driver): print(i)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
Last
python标准库中inspect 模块简单介绍_阿常呓语的专栏-CSDN博客
评论记录:
回复评论: