目录

前言

一、inspect模块总览

1、获取成员与判断

2、获取源代码

3、类与函数

4、调用栈

二、inspect模块方法的使用

1、getmembers

2、getcomments、getdocs

3、signature 获取方法和函数签名

4、类层次体系 getmro()

5、栈与帧 currentframe()、stack()


前言

inspect模块也被称为 检查现场对象。这里的重点在于“现场”二字,也就是当前运行的状态。

inspect模块提供了一些函数来了解现场对象,包括 模块、类、实例、函数和方法

inspect函数主要用于以下四个方面

  •   对是否是模块、框架、函数进行类型检查
  •   获取源码
  •   获取类或者函数的参数信息
  •   解析堆栈

本文章会先带大家大概了解一下inspect模块有哪些功能,以及有哪些功能函数,然后再结合实例,解释每个方法他们的使用场景以及使用方法。

一、inspect模块总览

1、获取成员与判断

1. inspect.getmembers(object[, predicate])

第二个参数通常可以根据需要调用如下16个方法;

返回值为object的所有成员,以(name,value)对组成的列表

  1. inspect.ismodule(object): 是否为模块

  2. inspect.isclass(object):是否为类

  3. inspect.ismethod(object):是否为方法(bound method written in python)

  4. inspect.isfunction(object):是否为函数(python function, including lambda expression)

  5. inspect.isgeneratorfunction(object):是否为python生成器函数

  6. inspect.isgenerator(object):是否为生成器

  7. inspect.istraceback(object): 是否为traceback

  8. inspect.isframe(object):是否为frame

  9. inspect.iscode(object):是否为code

  10. inspect.isbuiltin(object):是否为built-in函数或built-in方法

  11. inspect.isroutine(object):是否为用户自定义或者built-in函数或方法

  12. inspect.isabstract(object):是否为抽象基类

  13. inspect.ismethoddescriptor(object):是否为方法标识符

  14. inspect.isdatadescriptor(object):是否为数字标识符,数字标识符有__get__ 和__set__属性; 通常也有__name__和__doc__属性

  15. inspect.isgetsetdescriptor(object):是否为getset descriptor

  16. inspect.ismemberdescriptor(object):是否为member descriptor

2. inspect.getmoduleinfo(path): 返回一个命名元组<named tuple>(name, suffix, mode, module_type)

  name:模块名(不包括其所在的package)

suffix:

mode:open()方法的模式,如:'r', 'a'等

module_type: 整数,代表了模块的类型

3. inspect.getmodulename(path):根据path返回模块名(不包括其所在的package)

2、获取源代码

1. inspect.getdoc(object): 获取object的documentation信息

2. inspect.getcomments(object)

3. inspect.getfile(object): 返回对象的文件名

4. inspect.getmodule(object):返回object所属的模块名

5. inspect.getsourcefile(object): 返回object的python源文件名;object不能使built-in的module, class, mothod

6. inspect.getsourcelines(object):返回object的python源文件代码的内容,行号+代码行

7. inspect.getsource(object):以string形式返回object的源代码

3、类与函数

1. inspect.getclasstree(classes[, unique])

2. inspect.getargspec(func)

3. inspect.getargvalues(frame)

4. inspect.formatargspec(args[, varargs, varkw, defaults, formatarg, formatvarargs, formatvarkw, formatvalue, join])

5. inspect.formatargvalues(args[, varargs, varkw, locals, formatarg, formatvarargs, formatvarkw, formatvalue, join])

6. inspect.getmro(cls): 元组形式返回cls类的基类(包括cls类),以method resolution顺序;通常cls类为元素的第一个元素

7. inspect.getcallargs(func[, *args][, **kwds]):将args和kwds参数到绑定到为func的参数名;对bound方法,也绑定第一个参数(通常为self)到相应的实例;返回字典,对应参数名及其值;

4、调用栈

1. inspect.getframeinfo(frame[, context])

2. inspect.getouterframes(frame[, context])

3. inspect.getinnerframes(traceback[, context])

4. inspect.currentframe()

5. inspect.stack([context])

6. inspect.trace([context])

二、inspect模块方法的使用

1、getmembers

inspect.getmembers()函数用于发现对象的成员属性。返回的成员类型取决于我们所传入的对象类型。传入的参数可以是 模块、类、实例、函数、方法

1.1 语法

inspect.getmembers(object[, predicate])

object可以是 模块、类、实例、函数、方法;

predict表示的是谓语,可以是isclass(),ismodule()等等,用于筛选,看了后面例子就懂了。

1.2 使用场景

用于获取对象的成员属性

1.3 例子

1.3.1 传入参数为module

现在准备了两个py文件,example_inspect.py文件中存放了一些类和方法的定义,作为模块;do_inspect.py文件会将上个py文件当作模块导入;来看这个模块里面有哪些成员。如下

######################### example_inspect.py ##########################
def module_level_function(arg1, arg2, *args, **kwargs):"""This function is declare in the module"""local_variable = arg1 * 2return local_variableclass A(object):"""The A class"""def __init__(self, name):self.name = namedef get_name(self):"""Return the name of instance"""return self.name@classmethoddef test(cls):pass@staticmethoddef do_nothing():passinstance_of_a = A("simple_instance")class B(A):"""This is B classit is Derived from A"""# This method is not part of Adef do_something(self):"""Does some works"""def get_name(self):"""Overrides version from A"""return "B(" + self.name + ")"######################### do_inspect.py ##########################
import inspect
import example_inspectfor name, data in inspect.getmembers(example_inspect):if name.startswith("__"):continueprint("{} : {!r}".format(name, data))

输出:

# 输出
A : <class 'example_inspect.A'>
B : <class 'example_inspect.B'>
instance_of_a : <example_inspect.A object at 0x00000132B5F707F0>
module_level_function : <function module_level_function at 0x00000132B5F54598>

上面的代码有3个注意点:

1、我们将example_inspect.py作为模块传入getmembers()方法,可以打印出这个模块中所有的成员,并以元组列表形式放回。

2、注意到我在遍历 getmembers()方法时,使用了 if name.startwith("--"),这是为什么呢?因为模块有一些私有属性作为导入实现的一部分,还会包含一组__builtins__。这两个东西的列表非常长,我们一般也都不关心。所以使用if将他们过滤掉。

3、我们还可以将do_inspect.py写法改变一下,如下,利用getmembers的谓语参数,可以选择得到自己想要的成员变量

import inspect
import example_inspectfor name, data in inspect.getmembers(example_inspect, inspect.isclass):  # 修改了这里if name.startswith("__"):continueprint("{} : {!r}".format(name, data))#输出
# A : <class 'example_inspect.A'>
# B : <class 'example_inspect.B'>

再修改

import inspect
import example_inspectfor name, data in inspect.getmembers(example_inspect, inspect.isfunction):if name.startswith("__"):continueprint("{} : {!r}".format(name, data))#输出
# module_level_function : <function module_level_function at 0x000002A084C44598>

但是,当我们使用 is.method()时,会不会打印出class A、class B内的方法呢?看下面

所以当传入的参数为module时,不能打印出 类的方法。但是可以打印出 模块级别的函数。(与后面参数为 类 时做对比)

import inspect
import example_inspectfor name, data in inspect.getmembers(example_inspect, inspect.ismethod):if name.startswith("__"):continueprint("{} : {!r}".format(name, data))# 输出为空

1.3.2 传入参数为 类

example_inspect.py不变,修改do_inspect.py文件,如下

import inspect
import example_inspectfor name, data in inspect.getmembers(example_inspect.A):print("{} : {!r}".format(name, data))# 输出的一部分
"""
__reduce_ex__ : <method '__reduce_ex__' of 'object' objects>
__repr__ : <slot wrapper '__repr__' of 'object' objects>
__setattr__ : <slot wrapper '__setattr__' of 'object' objects>
__sizeof__ : <method '__sizeof__' of 'object' objects>
__str__ : <slot wrapper '__str__' of 'object' objects>
__subclasshook__ : <built-in method __subclasshook__ of type object at 0x0000029958B45D38>
__weakref__ : <attribute '__weakref__' of 'A' objects>
do_nothing : <function A.do_nothing at 0x0000018ED33E1950>
get_name : <function A.get_name at 0x0000018ED33E1840>
test : <bound method A.test of <class 'example_inspect.A'>>
"""

会打印出一堆结果,这里我只粘贴上了一部分,以双下划线开始的变量基本都是继承object得来的和一些自带的变量。但是注意到,打印出了 方法:get_name()和__init__() do_nothing() test()如果我们给类A添加了类变量,同样也会打印出来

当然我们可以使用 谓语 来筛选。

注意: 要查找一个类的成员,使用 iinspect.isfunction();而inspect.ismethod()谓语只识别实例的绑定的方法;

当然,如果类里面定义了类方法,ismethod会打印出这个类方法,因为类也是对象,而类方法就是与类绑定的方法

import inspect
import example_inspectfor name, data in inspect.getmembers(example_inspect.A, inspect.isfunction):print("{} : {!r}".format(name, data))# 输出
"""
__init__ : <function A.__init__ at 0x0000029E5CD517B8>
do_nothing : <function A.do_nothing at 0x0000029E5CD51950>
get_name : <function A.get_name at 0x0000029E5CD51840>
"""#########################################################################import inspect
import example_inspectfor name, data in inspect.getmembers(example_inspect.A, inspect.ismethod):print("{} : {!r}".format(name, data))# 输出
"""
test : <bound method A.test of <class 'example_inspect.A'>>
"""

继承下的情况

在B继承于A情况下,B拥有了A的方法,因此也被打印出来。

import inspect
import example_inspectfor name, data in inspect.getmembers(example_inspect.B, inspect.isfunction):print("{} : {!r}".format(name, data))# 输出
"""
__init__ : <function A.__init__ at 0x0000020DA3E217B8>
do_nothing : <function A.do_nothing at 0x0000020DA3E21950>
do_something : <function B.do_something at 0x0000020DA3E219D8>
get_name : <function B.get_name at 0x0000020DA3E21A60>
"""

1.3.2 传入参数为 实例

可以看出,类方法和实例方法都被打印出来,而静态方法被忽略掉

import inspect
import example_inspectfor name, data in inspect.getmembers(example_inspect.instance_of_a, inspect.ismethod):print("{} : {!r}".format(name, data))# 输出
"""
__init__ : <bound method A.__init__ of <example_inspect.A object at 0x00000202E9387208>>
get_name : <bound method A.get_name of <example_inspect.A object at 0x00000202E9387208>>
test : <bound method A.test of <class 'example_inspect.A'>>
"""

2、getcomments、getdocs

这两个函数在我们编程中用到的很少。这里也就不做介绍了。后面用到的话,直接去官方文档看就可以了。

3、获取源代码:getsource() 和 getsourcelines()

如果可以得到一个模块的 .py文件,则可以使用getsource() 和 getsourcelines()获取类或者方法的原始代码。

多的不说,看代码。

import inspect
import example_inspectprint(inspect.getsource(example_inspect.A))# 输出
"""
class A(object):"""The A class"""def __init__(self, name):self.name = namedef get_name(self):"""Return the name of instance"""return self.name@classmethoddef test(cls):pass@staticmethoddef do_nothing():pass
"""####################################################import inspect
import example_inspectprint(inspect.getsource(example_inspect.A.get_name))# 输出
"""def get_name(self):"""Return the name of instance"""return self.name"""

getsourcelines()的返回值是一个tuple,其中包含一个字符串列表,和文件中源代码出现的起始行号,如下

import inspect
import example_inspectprint(inspect.getsourcelines(example_inspect.A.get_name))# 输出
"""
(['    def get_name(self):\n', '        """Return the name of instance"""\n', '        return self.name\n'], 13)
"""

3、signature 获取方法和函数签名

3.1 (补充知识)函数签名是什么?

函数签名对象,表示调用函数的方式,即定义了函数的输入和输出

一个函数由这么bai几部分组成,函数名、参数个数、参数类型、返回值。函数签名就是指 参数个数、参数类型

那么为什么会有参数签名这么个东西呢?

答:函数在重载时,利用函数签名的不同(即参数个数与类型的不同)来区别调用者到底调用的是那个方法。就如同下面两个方法,语言正是通过他们的函数签名不同,来区别同函数名但是不同参数的函数。

def test(a,b,c):passdef test(a,b,c,d):pass

3.2(补充知识)python函数的参数分类

共有5类,分别是

  • POSITIONAL_OR_KEYWORD:   # 普通参数, python函数的参数多数属于此类
  • VAR_POSITIONAL:*args,定位参数元组
  • VAR_KEYWORD:**kwargs,关键字参数字典
  • KEYWORD_ONLY: 仅限关键字参数, 类似于 下边d=100 的这种
  • POSITIONAL_ONLY(不用管,很难用到):仅限定位参数, python声名的函数不支持, 但是有些c语言实现且不接受关键字参数的函数, 例如: divmod 支持
# 5大类
ParameterKind = [{"POSITIONAL_OR_KEYWORD": "可以通过定位参数和关键字参数传入的形参, python函数的参数多数属于此类"},  # 普通参数{"VAR_POSITIONAL": "定位参数元组"},  # *args{"VAR_KEYWORD": "关键字参数字典"},  # **kwargs{"KEYWORD_ONLY": "仅限关键字参数"},  # 类似于 下边d=100 的这种{"POSITIONAL_ONLY": "仅限定位参数, python声名的函数不支持, 但是有些c语言实现且不接受关键字参数的函数, 例如: divmod 支持"},
]# 前四类
from inspect import signaturedef func(a, b, c=10, *args, d=100, **kwargs):print(a, b, c, args, d, kwargs)sig_func = signature(func)for name_, para_ in sig_func.parameters.items():print(para_.name, para_.kind, para_.default)"""参数        参数类型                   参数默认值a       POSITIONAL_OR_KEYWORD     <class 'inspect._empty'>b       POSITIONAL_OR_KEYWORD     <class 'inspect._empty'>c       POSITIONAL_OR_KEYWORD     10args    VAR_POSITIONAL            <class 'inspect._empty'>d       KEYWORD_ONLY              100kwargs  VAR_KEYWORD               <class 'inspect._empty'>
"""# 特殊的POSITIONAL_ONLYsig_divmod = signature(divmod)for _, _para in sig_divmod.parameters.items():          # print(_para.name, _para.kind, _para.default)
"""x     POSITIONAL_ONLY     <class 'inspect._empty'>y     POSITIONAL_ONLY     <class 'inspect._empty'>
"""

3.2 使用inspect.signature获取函数的签名

使用inspect.signature获取函数的签名后,所有参数都以key-value的形式存放在Parameter中。我们继续是使用inspect_example.py的代码作为被检测对象。看下面的代码。

import inspect
import example_inspectsig = inspect.signature(example_inspect.module_level_function)
print(sig.parameters)print("\nParameter details:")
for name, param in sig.parameters.items():if param.kind == inspect.Parameter.POSITIONAL_OR_KEYWORD:print("    {} (POSITIONAL_OR_KEYWORD)".format(name))elif param.kind == inspect.Parameter.VAR_POSITIONAL:print("    {} (VAR_POSITIONAL)".format(name))elif param.kind == inspect.Parameter.VAR_KEYWORD:print("    {} (VAR_KEYWORD)".format(name))elif param.kind == inspect.Parameter.KEYWORD_ONLY:print("    {} (KEYWORD_ONLY)".format(name))# 输出
"""
OrderedDict([('arg1', <Parameter "arg1">), ('arg2', <Parameter "arg2">), ('args', <Parameter "*args">), ('kwargs', <Parameter "**kwargs">)])Parameter details:arg1 (POSITIONAL_OR_KEYWORD)arg2 (POSITIONAL_OR_KEYWORD)args (VAR_POSITIONAL)kwargs (VAR_KEYWORD)
"""

3.4使用inspect.signature创建签名

from inspect import Signature, Parameter# 创建一个函数参数列表,列表内的元素由类Parameter的实例组成
# Parameter实例化时,依次接受参数名、参数类型、默认值和参数注解
# 默认值和参数类型默认为空,这里的空值不是None,而是Parameter.empty,代表没有值
params = [Parameter('x', Parameter.POSITIONAL_OR_KEYWORD),Parameter('y', Parameter.POSITIONAL_OR_KEYWORD, default=9),Parameter('z', Parameter.VAR_KEYWORD)]# 使用Signature类,接受函数参数列表,实例化出函数签名实例
sig = Signature(params)
print(sig)

这种方式获取的 sig 和我们之前使用  sig = inspect.signature(example_inspect.module_level_function) 语句获取的sig是同一类对象,本质上没有任何区别。

那么,我们把这些参数给扣出来又有什么用呢?

我们可以先为这些参数赋值,然后再去调用我们的函数。就实现了:先给参数赋值,然后再去和函数发生关联、调用。

见3.5

3.5 使用bind() 、bind_partial() 方法给匹配签名

使用函数签名的bind的方法,检查函数参数是否匹配签名。

继续延续 inspect_example.py的例子,通过函数签名的bind方法,接受函数参数。如果匹配,返回参数BoundArguments实例,如果不匹配,则抛出TypeError,并给出详细的异常信息。

通过BoundArguments实例的属性,可以获取函数签名、参数的值等内容。

并且,bind()函数必须指定 必传参数,默认参数不会计入到 BoundArguments中

bind_partial()函数也必须指定必传参数,默认参数不会计入到 BoundArguments中;但是如果使用了apply_defaults()方法,则默认参数也会存入arguments中。

可以认为  没有执行partial.apply_defaults()的bind_partial()函数,和bind()函数没有什么区别

也许你对上面三句话不太懂,那么好好看下面的代码例子,你就懂了。

bind()方法

################### inspect_example.py ###############################
def module_level_function(arg1, arg2="xxx", *args, **kwargs):"""This function is declare in the module"""local_variable = arg1 * 2return local_variable################### do_inspect.py ##############################
import inspect
import example_inspectsig = inspect.signature(example_inspect.module_level_function)bound = sig.bind("this is arg1","this is arg2"
)
print(bound)
example_inspect.module_level_function(*bound.args, **bound.kwargs)#输出,可以看到BoundArguments中只有arg1这个参数,而即使arg2有默认参数,也没有将arg2传入BoundArguments
<BoundArguments (arg1='this is arg1')>
this is arg1this is arg1
xxx

bind_partial()方法

################### inspect_example.py ###############################
def module_level_function(arg1, arg2="xxx", *args, **kwargs):"""This function is declare in the module"""local_variable = arg1 * 2return local_variable################### do_inspect.py ##############################import inspect
import example_inspectsig = inspect.signature(example_inspect.module_level_function)bound = sig.bind_partial("this is arg1","this is arg2"
)
print(bound)
example_inspect.module_level_function(*bound.args, **bound.kwargs)# 输出,可以看出此时bind_partial 和bind 没啥区别
"""
<BoundArguments (arg1='this is arg1')>
this is arg1this is arg1
xxx
"""

执行了partial.apply_defaults()方法的bind_partial()方法

################### inspect_example.py ###############################
def module_level_function(arg1, arg2="xxx", *args, **kwargs):"""This function is declare in the module"""local_variable = arg1 * 2return local_variable################### do_inspect.py ##############################
import inspect
import example_inspectsig = inspect.signature(example_inspect.module_level_function)bound = sig.bind_partial("this is arg1"
)
bound.apply_defaults()  # 加了这句
print(bound)
example_inspect.module_level_function(*bound.args, **bound.kwargs)# 输出,现在所有的默认参数都传入了BoundArguments对象
"""
<BoundArguments (arg1='this is arg1', arg2='xxx', args=(), kwargs={})>
this is arg1this is arg1
xxx
"""

4、类层次体系 getmro()

这里只介绍getmro()函数,它接受的参数为 类,然后返回值是一个 类的tuple,它会解析出传入类的所有基类,并按照mro的顺序排列。(不从mro的,自行百度吧,比较简单的概念就不说了)

看下面的例子

################### inspect_example.py ###############################
class A(object):"""The A class"""def __init__(self, name):self.name = namedef get_name(self):"""Return the name of instance"""return self.name@classmethoddef test(cls):pass@staticmethoddef do_nothing():passclass B(A):"""This is B classit is Derived from A"""# This method is not part of Adef do_something(self):"""Does some works"""def get_name(self):"""Overrides version from A"""return "B(" + self.name + ")"################### mro_example.py ###############################
import inspect
import example_inspectclass C:passclass C_First(C, example_inspect.B):passprint(inspect.getmro(C_First))#执行后,输出
"""
(<class '__main__.C_First'>, <class '__main__.C'>, <class 'example_inspect.B'>, <class 'example_inspect.A'>, <class 'object'>)
"""

5、栈与帧 currentframe()、stack()

5.1 currentframe()

为了讲清楚这里,需要补充一些知识:

5.1.1、栈帧是什么,以及程序调用与栈帧

参考这篇链接https://www.cnblogs.com/samo/articles/3092895.html

5.1.2、frame对象

看完了关于栈帧的文章,相信大家已经知道栈帧是什么,以及函数调用时是如何将信息存入栈帧的。

我们经常说的 某一帧 指的就是一个函数存储在栈中的所有信息 就是一帧, 千万不要以为某一帧就是说的某一条数据,帧是一个块的概念。

那么frame对象又是什么呢?

Frame对象表示执行帧,表示程序运行时函数调用栈中的某一帧。

想要获得某个函数相关的栈帧,则必须在调用这个函数且这个函数尚未返回时获取。可以使用sys模块的_getframe()函数、或inspect模块的currentframe()函数获取当前栈帧。

而frame包含了一些属性,其实这些属性对应的就是我们在栈帧里存储的数据,如下

特殊只读属性
属性 说明
f_back 前一个堆栈帧(朝向调用者),如果这是底部堆栈帧则为None
f_code 在这个框架中执行的Code对象
f_locals 用于查找局部变量的字典
f_globals 用于全局变量
f_builtins 用于内置名称
f_restricted 表示该函数是否在限制执行模式下执行的标志
f_lasti 给出精确的指令(这是代码对象的字节码字符串的索引)
特殊可写属性
f_trace  
f_exc_type  
f_exc_value  
f_exc_traceback  
f_lineno 当前代码在文件中的哪一行

上面这些参数,大家可以通过ID E调试,看到他们的组成。还有很多参数我没有介绍。我这里只给出一个例子,大家可以自己去调试。

import inspect
import pprintdef recurse(limit, keyword="default", * ,kwonly="must be named"):local_variable= "."*limitkeyword = "change value of argument"frame = inspect.currentframe()print("line {} of {}".format(frame.f_lineno,frame.f_code.co_filename))pprint.pprint(frame.f_locals)print("\n")if limit <= 0:returnrecurse(limit-1)return local_variableif __name__ == '__main__':recurse(2)#输出
"""
line 8 of C:/Users/ASUS/Desktop/项目资料/模型引擎项目/luigi_process_test/code/standard_test/do_inspect.py
{'frame': <frame at 0x0000018E47160828, file 'C:/Users/ASUS/Desktop/项目资料/模型引擎项目/luigi_process_test/code/standard_test/do_inspect.py', line 9, code recurse>,'keyword': 'change value of argument','kwonly': 'must be named','limit': 2,'local_variable': '..'}line 8 of C:/Users/ASUS/Desktop/项目资料/模型引擎项目/luigi_process_test/code/standard_test/do_inspect.py
{'frame': <frame at 0x0000018E46AC14D8, file 'C:/Users/ASUS/Desktop/项目资料/模型引擎项目/luigi_process_test/code/standard_test/do_inspect.py', line 9, code recurse>,'keyword': 'change value of argument','kwonly': 'must be named','limit': 1,'local_variable': '.'}line 8 of C:/Users/ASUS/Desktop/项目资料/模型引擎项目/luigi_process_test/code/standard_test/do_inspect.py
{'frame': <frame at 0x0000018E46AC5668, file 'C:/Users/ASUS/Desktop/项目资料/模型引擎项目/luigi_process_test/code/standard_test/do_inspect.py', line 9, code recurse>,'keyword': 'change value of argument','kwonly': 'must be named','limit': 0,'local_variable': ''}
"""

5.2 stack()

使用stack()函数,还可以访问到当前帧到第一个调用者的所有栈帧。这个例子与上面的例子相似。只不过它会一直等待,直到递归结束,再打印栈信息。

其实stack()获取的就是frame的列表,是一个按照调用顺序包含了所有栈帧的列表。

那么,它有什么用处呢?

我用它排插过错误,通过定位栈,来定位错误的来源。其他的场景还没有用过。如果后面有的话,再补充。

import inspect
import pprintdef show_stack():for level in inspect.stack():print("{}[{}]\n -> {}".format(level.frame.f_code.co_filename,level.lineno,level.code_context[level.index].strip()))pprint.pprint(level.frame.f_locals)print("\n")def recurse(limit):local_variable = "." * limitif limit <= 0:show_stack()returnrecurse(limit - 1)return local_variableif __name__ == '__main__':recurse(2)#输出
"""
C:/Users/ASUS/Desktop/项目资料/模型引擎项目/luigi_process_test/code/standard_test/do_inspect.py[6]-> for level in inspect.stack():
{'level': FrameInfo(frame=<frame at 0x000001A6D0FF8798, file 'C:/Users/ASUS/Desktop/项目资料/模型引擎项目/luigi_process_test/code/standard_test/do_inspect.py', line 9, code show_stack>, filename='C:/Users/ASUS/Desktop/项目资料/模型引擎项目/luigi_process_test/code/standard_test/do_inspect.py', lineno=6, function='show_stack', code_context=['    for level in inspect.stack():\n'], index=0)}C:/Users/ASUS/Desktop/项目资料/模型引擎项目/luigi_process_test/code/standard_test/do_inspect.py[16]-> show_stack()
{'limit': 0, 'local_variable': ''}C:/Users/ASUS/Desktop/项目资料/模型引擎项目/luigi_process_test/code/standard_test/do_inspect.py[18]-> recurse(limit - 1)
{'limit': 1, 'local_variable': '.'}C:/Users/ASUS/Desktop/项目资料/模型引擎项目/luigi_process_test/code/standard_test/do_inspect.py[18]-> recurse(limit - 1)
{'limit': 2, 'local_variable': '..'}C:/Users/ASUS/Desktop/项目资料/模型引擎项目/luigi_process_test/code/standard_test/do_inspect.py[23]-> recurse(2)
{'__annotations__': {},'__builtins__': <module 'builtins' (built-in)>,'__cached__': None,'__doc__': None,'__file__': 'C:/Users/ASUS/Desktop/项目资料/模型引擎项目/luigi_process_test/code/standard_test/do_inspect.py','__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000001A6CFA71CC0>,'__name__': '__main__','__package__': None,'__spec__': None,'inspect': <module 'inspect' from 'C:\\Users\\ASUS\\Anaconda3\\lib\\inspect.py'>,'pprint': <module 'pprint' from 'C:\\Users\\ASUS\\Anaconda3\\lib\\pprint.py'>,'recurse': <function recurse at 0x000001A6D0444598>,'show_stack': <function show_stack at 0x000001A6CFAAC1E0>}"""

python基础:inspect模块各函数的用法相关推荐

  1. Python基础教程:return函数的用法

    1.return函数 def face(name):return name+'的脸蛋,'def body(name):return name+'的身材'def main(a,b):return '我梦 ...

  2. Python基础之模块和包

    Python基础之模块和包 本节将介绍Python中的模块和包的概念及基本用法. 模块 简单来说模块就是一个python文件,我们可以将一些常量.函数.类等封装到一个模块中,然后在程序中使用该模块.模 ...

  3. python items函数用法,Python中dictionary items()系列函数的用法实例

    本文实例讲述了Python中dictionary items()系列函数的用法,对Python程序设计有很好的参考借鉴价值.具体分析如下: 先来看一个示例: import html # availab ...

  4. python基础——使用模块

    python基础--使用模块 Python本身就内置了很多非常有用的模块,只要安装完毕,这些模块就可以立刻使用. 我们以内建的sys模块为例,编写一个hello的模块: #!/usr/bin/env ...

  5. 十五. Python基础(15)--内置函数-1

    十五. Python基础(15)--内置函数-1 1 ● eval(), exec(), compile() 执行字符串数据类型的python代码 检测#import os 'import' in c ...

  6. Python基础(五)--函数

    目录 Python基础(五)--函数 1 函数的作用 1.1 函数定义与调用 1.2 函数的作用 1.3 空语句 2 参数与返回值 2.1 函数的参数 2.2 函数的返回值 2.3 返回多个值 3 参 ...

  7. 用于生成随机数的python标准库模块是_详解Python基础random模块随机数的生成

    详解Python基础random模块随机数的生成 来源:中文源码网    浏览: 次    日期:2019年11月5日 [下载文档:  详解Python基础random模块随机数的生成.txt ] ( ...

  8. python random库生成伯努利随机数的方法_详解Python基础random模块随机数的生成

    随机数参与的应用场景大家一定不会陌生,比如密码加盐时会在原密码上关联一串随机数,蒙特卡洛算法会通过随机数采样等等.Python内置的random模块提供了生成随机数的方法,使用这些方法时需要导入ran ...

  9. python enumerate函数_关于python中enumerate和zip函数的用法及举例

    关于python中enumerate和zip函数的用法及举例 关于enumerate函数: enumerate函数可以同时返回列表或元组等可迭代对象的下标和内容,但实际上,enumerate函数实际返 ...

最新文章

  1. SAP MM 按采购订单查询付款信息的报表?
  2. 自动驾驶发展调查:产业化还需技术“破冰”
  3. equinox_轻松使用Linux Equinox桌面环境
  4. 日记、2021/9/30
  5. 简单实用的web打印方案-网页精准打印
  6. java 类的对象是什么意思_java中类和对象的概念
  7. Enrico Da Vincent
  8. python 高级函数补充
  9. Mybatis之错误:Invalid bound statement (not found)
  10. MySQL系列之STRAIGHT JOIN用法简介
  11. windows批处理:start的用法
  12. Ros yocs_velocity_smoother 保姆级部署教程
  13. SaaS平台产品架构设计
  14. 扔掉你 WINDOWS 中的盗版软件吧
  15. 加速应用开发 | Firebase Summit 2021 精彩回顾
  16. c#如何实现软件授权后才能使用?
  17. “人货场”模型,该怎么搭建?
  18. libpng warning: iCCP: known incorrect sRGB profile 警告,问题解决
  19. 单独关闭腾讯会议或者钉钉的声音
  20. oracle数据库测评

热门文章

  1. 《谁说菜鸟不会数据分析》
  2. java情人节_又是一个浪漫的Java特效,这个情人节脱单就靠他了
  3. JS隐藏/显示div标签
  4. 分布式锁以及三种加锁方式
  5. 【PF三维路径规划】基于matlab改进的粒子滤波无人机三维路径规划【含Matlab源码 1269期】
  6. 申报绿色工厂的流程、费用和资料大全。
  7. 智能计算—模糊计算总结
  8. 西门子io-link配置工具 s7-pct
  9. 注册消防工程师考试模拟学习系统基于大数据、人工智能、3D系统研发
  10. 腾讯微服务开源项目再摘信通院OSCAR开源大奖