29.12. inspect - 检查活动对象

源程序代码︰Lib/inspect.py

inspect模块提供了一些有用的函数来帮助获取有关活动对象(如模块,类,方法,函数,跟踪,框架对象和代码对象)的信息。例如,它可以帮助您检查类的内容,检索方法的源代码,提取和格式化函数的参数列表,或获取显示详细追溯所需的所有信息。

这个模块提供了四种主要的服务:类型检查,获取源代码,检查类和函数,以及检查解释器堆栈。

29.12.1. 类型和成员

getmembers()函数检索对象(如类或模块)的成员。名称以“is”开头的函数主要提供为getmembers()的第二个参数的方便选择。它们还可以帮助您确定何时可以找到以下特殊属性:

类型属性描述
模块__doc__文档字符串
__file__文件名(内建模块缺少)
__doc__文档字符串
__name__定义此类的名称
__qualname__限定名称
__module__定义此类的模块的名称
方法__doc__文档字符串
__name__定义此方法的名称
__qualname__合格名称
__func__函数对象包含方法的实现
__self__此方法所绑定的实例,或None
函数__doc__文档字符串
__name__定义此函数的名称
__qualname__合格名称
__code__包含编译函数bytecode的代码对象
__defaults__位置或关键字参数的任何默认值的元组
__kwdefaults__仅映射关键字参数的任何默认值
__globals__全局命名空间,其中定义了此函数
__annotations__将参数名称映射到注解; "return"键保留用于返回注解。
tracebacktb_frame框架对象在此级别
tb_lasti最后尝试的指令在字节码中的索引
tb_linenoPython源代码中的当前行号
tb_next下一个内部跟踪对象(由此级别调用)
框架f_backnext outer框架对象(this框架的调用者)
f_builtinsbuiltins命名空间
f_code代码对象在此框架中执行
f_globals这个框架看到的全局命名空间
f_lasti最后尝试的指令在字节码中的索引
f_linenoPython源代码中的当前行号
f_localsthis框架看到的本地命名空间
f_restricted0或1(如果框架处于受限执行模式)
f_trace此框架的跟踪功能,或None
codeco_argcount参数数量(不包括*或** args)
co_code原始编译字节码字符串
co_consts字节码中使用的常量的元组
co_filename创建此代码对象的文件的名称
co_firstlinenoPython源代码中的第一行数
co_flags位图:1 =优化| 2 = newlocals | 4 = * arg | 8 = ** arg
co_lnotab行编号到字节码索引的编码映射
co_name定义此代码对象的名称
co_names局部变量的名称的元组
co_nlocals局部变量的数量
co_stacksize虚拟机栈空间需要
co_varnames元组名称的参数和局部变量
生成器__name__名称
__qualname__合格名称
gi_frame框架
gi_running是生成器运行吗?
gi_code
gi_yieldfrom对象被产生 None
协程__name__名称
__qualname__合格名称
cr_await正在等待的对象,或None
cr_frame框架
cr_running是协程运行?
cr_code
内置__doc__文档字符串
__name__此函数或方法的原始名称
__qualname__合格名称
__self__方法绑定的实例,或None

在版本3.5中已更改:__qualname__gi_yieldfrom属性添加到生成器。

生成器的__name__属性现在从函数名称而不是代码名称设置,现在可以修改。

inspect.getmembers(object[, predicate])

返回按名称排序的(名称,值)对的列表中的对象的所有成员。如果提供了可选的谓词参数,则只包括谓词返回真值的成员。

注意

getmembers()只会返回元类中定义的类属性,当参数是类且这些属性已在元类“custom __dir__()

inspect.getmoduleinfo(path)

返回named tuple ModuleInfo(name, suffix, mode, module_type) t6>的值描述如何解释由path标识的文件(如果是模块)或NoneIn that tuple, name is the name of the module without the name of any enclosing package, suffix is the trailing part of the file name (which may not be a dot-delimited extension), mode is the open() mode that would be used ('r' or 'rb'), and module_type is an integer giving the type of the module. module_type将具有可与imp模块中定义的常量进行比较的值;有关模块类型的更多信息,请参阅该模块的文档。

自版本3.3后已弃用:您可以根据importlib.machinery中列出的受支持后缀来检查文件路径的后缀,以推断相同的信息。

inspect.getmodulename(path)

返回由文件path命名的模块的名称,而不包括封装包的名称。将针对importlib.machinery.all_suffixes()中的所有条目检查文件扩展名。如果匹配,则返回最终路径组件,并删除扩展名。否则,返回None

请注意,此函数为实际的Python模块返回一个有意义的名称 - 潜在引用Python包的路径仍将返回None

在版本3.3中已更改:此函数现在直接基于importlib,而不是已弃用的getmoduleinfo()

inspect.ismodule(object)

如果对象是模块,则返回true。

inspect.isclass(object)

如果对象是类,则返回true,无论是内建还是在Python代码中创建。

inspect.ismethod(object)

如果对象是用Python编写的绑定方法,则返回true。

inspect.isfunction(object)

如果对象是Python函数,则返回true,其中包含由lambda表达式创建的函数。

inspect.isgeneratorfunction(object)

如果对象是Python生成器函数,则返回true。

inspect.isgenerator(object)

如果对象是生成器,则返回true。

inspect.iscoroutinefunction(object)

如果对象是coroutine function(用async def语法定义的函数),则返回true。

版本3.5中的新功能。

inspect.iscoroutine(object)

如果对象是由async def函数创建的coroutine,则返回true。

版本3.5中的新功能。

inspect.isawaitable(object)

如果对象可以在await表达式中使用,则返回true。

也可以用来区分基于生成器的协程和常规生成器:

def gen():
    yield
@types.coroutine
def gen_coro():
    yield

assert not isawaitable(gen())
assert isawaitable(gen_coro())

版本3.5中的新功能。

inspect.istraceback(object)

如果对象是回溯,则返回true。

inspect.isframe(object)

如果对象是框架,则返回true。

inspect.iscode(object)

如果对象是代码,则返回true。

inspect.isbuiltin(object)

如果对象是内建函数或绑定内建方法,则返回true。

inspect.isroutine(object)

如果对象是用户定义或内建函数或方法,则返回true。

inspect.isabstract(object)

如果对象是抽象基类,则返回true。

inspect.ismethoddescriptor(object)

如果ismethod()isclass()isfunction()isbuiltin()都是true。

例如,这对于int.__add__是正确的。通过此测试的对象具有__get__()方法,但不是__set__()方法,但除此之外,属性集也不同。__name__属性通常是合理的,而__doc__通常是。

Methods implemented via descriptors that also pass one of the other tests return false from the ismethoddescriptor() test, simply because the other tests promise more – you can, e.g., count on having the __func__ attribute (etc) when an object passes ismethod().

inspect.isdatadescriptor(object)

如果对象是数据描述器,则返回true。

数据描述器具有__get____set__方法。示例是属性(在Python中定义),getsets和成员。后两者在C中定义,并且有更多的特定测试可用于这些类型,这在Python实现上是稳健的。通常,数据描述器还将具有__name____doc__属性(属性,获取和成员都具有这些属性),但不能保证。

inspect.isgetsetdescriptor(object)

如果对象是getset描述器,返回true。

CPython实现细节: getsets是通过PyGetSetDef结构在扩展模块中定义的属性。对于没有这种类型的Python实现,此方法将始终返回False

inspect.ismemberdescriptor(object)

返回true如果对象是成员描述器。

CPython实现细节:成员描述器是通过PyMemberDef结构在扩展模块中定义的属性。对于没有这种类型的Python实现,此方法将始终返回False

29.12.2. Retrieving source code

inspect.getdoc(object)

获取对象的文档字符串,用cleandoc()清理。如果未提供对象的文档字符串,并且对象是类,方法,属性或描述器,则从继承层次结构检索文档字符串。

在3.5版本中已更改:如果未覆盖,现在将继承文档字符串。

inspect.getcomments(object)

在单个字符串中返回紧接对象源代码(对于类,函数或方法)之前或Python源文件(如果对象是模块)顶部的任何注释行。

inspect.getfile(object)

返回定义了对象的(文本或二进制)文件的名称。如果对象是内建模块,类或函数,则会失败并显示TypeError

inspect.getmodule(object)

尝试猜测在哪个模块中定义了对象。

inspect.getsourcefile(object)

返回定义了对象的Python源文件的名称。如果对象是内建模块,类或函数,则会失败并显示TypeError

inspect.getsourcelines(object)

返回对象的源行和起始行号的列表。参数可以是模块,类,方法,函数,回溯,框架或代码对象。源代码作为对应于对象的行的列表返回,并且行号指示在原始源文件中在何处找到第一行代码。如果无法检索源代码,则会引发OSError

在版本3.3中更改: OSError,而不是IOError,现在是前者的别名。

inspect.getsource(object)

返回对象的源代码的文本。参数可以是模块,类,方法,函数,回溯,框架或代码对象。源代码作为单个字符串返回。如果无法检索源代码,则会引发OSError

在版本3.3中更改: OSError,而不是IOError,现在是前者的别名。

inspect.cleandoc(doc)

从缩进到与代码块对齐的文档字符串中清除缩进。

所有前导空白都从第一行删除。可以从第二行向前均匀删除的任何前导空白被删除。随后删除开始和结束处的空行。此外,所有选项卡都将展开为空格。

29.12.3. Introspecting callables with the Signature object

版本3.3中的新功能。

声明对象表示可调用对象的调用声明及其返回注解。要检索声明对象,请使用signature()函数。

inspect.signature(callable, *, follow_wrapped=True)

返回给定callableSignature对象:

>>> from inspect import signature
>>> def foo(a, *, b:int, **kwargs):
...     pass

>>> sig = signature(foo)

>>> str(sig)
'(a, *, b:int, **kwargs)'

>>> str(sig.parameters['b'])
'b:int'

>>> sig.parameters['b'].annotation
<class 'int'>

接受范围广泛的python可调用对象,从纯函数和类到functools.partial()对象。

如果不支持声明,则引发ValueError,如果不支持该类型的对象,则为TypeError

新版本3.5: follow_wrapped参数。通过False可获得callable的声明(callable.__wrapped__将不会用于解开装饰的可调用项)。

注意

在Python的某些实现中,一些可调用项可能不是自省的。例如,在CPython中,C中定义的一些内建函数不提供有关其参数的元数据。

class inspect.Signature(parameters=None, *, return_annotation=Signature.empty)

声明对象表示函数的调用声明及其返回注解。对于函数接受的每个参数,它在其parameters容器中存储Parameter对象。

可选的参数参数是Parameter对象的序列,其被验证以检查没有具有重复名称的参数,并且参数以正确的顺序,即仅位置首先,然后是位置或关键字,并且具有默认值的参数遵循没有默认值的参数。

可选的return_annotation参数,可以是任意的Python对象,是可调用的“return”注解。

声明对象为immutable使用Signature.replace()来创建修改的副本。

在版本3.5中更改:签名对象可拾取和哈希。

empty

一个特殊的类级别标记来指定没有返回注解。

parameters

参数名称到对应的Parameter对象的有序映射。

return_annotation

callable的“return”注解。如果callable没有“return”注解,则此属性设置为Signature.empty

bind(*args, **kwargs)

创建从位置和关键字参数到参数的映射。返回BoundArguments如果*args**kwargs匹配声明,或引用TypeError

bind_partial(*args, **kwargs)

以与Signature.bind()相同的方式工作,但允许省略一些必需的参数(模仿functools.partial()行为)。如果传递的参数与声明不匹配,则返回BoundArguments或引发TypeError

replace(*[, parameters][, return_annotation])

基于实例替换创建一个新的声明实例。可以通过不同的parameters和/或return_annotation覆盖基本声明的相应属性。要从复制的声明中删除return_annotation,请传入Signature.empty

>>> def test(a, b):
...     pass
>>> sig = signature(test)
>>> new_sig = sig.replace(return_annotation="new return anno")
>>> str(new_sig)
"(a, b) -> 'new return anno'"
classmethod from_callable(obj, *, follow_wrapped=True)

返回给定可调用objSignature(或其子类)对象。传递follow_wrapped=False以取消声明obj,而不打开其__wrapped__链。

此方法简化了Signature的子类化:

class MySignature(Signature):
    pass
sig = MySignature.from_callable(min)
assert isinstance(sig, MySignature)

版本3.5中的新功能。

class inspect.Parameter(name, kind, *, default=Parameter.empty, annotation=Parameter.empty)

参数对象为immutable您可以使用Parameter.replace()来创建修改的副本,而不是修改参数对象。

在版本3.5中更改:参数对象是可拾取和哈希的。

empty

一个特殊的类级别标记,用于指定缺省值和注释的缺失。

name

参数的名称作为字符串。名称必须是有效的Python标识符。

default

参数的默认值。如果参数没有默认值,则此属性设置为Parameter.empty

annotation

参数的注释。如果参数没有注释,则此属性设置为Parameter.empty

kind

描述参数值如何绑定到参数。可能的值(可通过Parameter访问,如Parameter.KEYWORD_ONLY):

名称含义
POSITIONAL_ONLY

值必须作为位置参数提供。

Python没有明确的定义位置参数的语法,但许多内建和扩展模块函数(特别是那些只接受一个或两个参数的函数)接受它们。

POSITIONAL_OR_KEYWORD值可以作为关键字或位置参数提供(这是在Python中实现的函数的标准绑定行为。)
VAR_POSITIONAL没有绑定到任何其他参数的位置参数的元组。这对应于Python函数定义中的*args参数。
KEYWORD_ONLY值必须作为关键字参数提供。仅限关键字的参数是在Python函数定义中的**args条目后出现的参数。
VAR_KEYWORD未绑定到任何其他参数的关键字参数的dict。这对应于Python函数定义中的**kwargs参数。

示例:print all all-only arguments without没有默认值:

>>> def foo(a, b, *, c, d=10):
...     pass

>>> sig = signature(foo)
>>> for param in sig.parameters.values():
...     if (param.kind == param.KEYWORD_ONLY and
...                        param.default is param.empty):
...         print('Parameter:', param)
Parameter: c
replace(*[, name][, kind][, default][, annotation])

Create a new Parameter instance based on the instance replaced was invoked on. To override a Parameter attribute, pass the corresponding argument. To remove a default value or/and an annotation from a Parameter, pass Parameter.empty.

>>> from inspect import Parameter >>> param = Parameter('foo', Parameter.KEYWORD_ONLY, default=42) >>> str(param) 'foo=42' >>> str(param.replace()) # Will create a shallow copy of 'param' 'foo=42' >>> str(param.replace(default=Parameter.empty, annotation='spam')) "foo:'spam'" 

Changed in version 3.4: In Python 3.3 Parameter objects were allowed to have name set to None if their kind was set to POSITIONAL_ONLY. 这不再允许。

class inspect.BoundArguments

Signature.bind()Signature.bind_partial()调用的结果。保存参数到函数参数的映射。

arguments

参数名称到参数值的有序,可变映射(collections.OrderedDict)。仅包含显式绑定的参数。arguments的变化将反映在argskwargs中。

应与Signature.parameters结合使用以用于任何参数处理目的。

注意

参数Signature.bind()Signature.bind_partial()依赖于默认值的参数将被跳过。但是,如果需要,请使用BoundArguments.apply_defaults()添加它们。

args

位置参数值的元组。arguments属性动态计算。

kwargs

关键字参数值的字典。arguments属性动态计算。

signature

对父Signature对象的引用。

apply_defaults()

为缺少的参数设置默认值。

对于可变位置参数(*args),默认值为空元组。

对于变量关键字参数(**kwargs),默认值为空。

>>> def foo(a, b='ham', *args): pass
>>> ba = inspect.signature(foo).bind('spam')
>>> ba.apply_defaults()
>>> ba.arguments
OrderedDict([('a', 'spam'), ('b', 'ham'), ('args', ())])

版本3.5中的新功能。

argskwargs属性可用于调用函数:

def test(a, *, b):
    ...

sig = signature(test)
ba = sig.bind(10, b=20)
test(*ba.args, **ba.kwargs)

也可以看看

PEP 362 - 函数声明对象。
详细规范,实现细节和示例。

29.12.4. Classes and functions

inspect.getclasstree(classes, unique=False)

将给定的类列表排列到嵌套列表的层次结构中。在出现嵌套列表时,它包含从其列紧接在列表之前的类派生的类。每个条目是一个2元组,包含一个类和其基类的元组。如果unique参数为true,则在给定列表中的每个类的返回结构中只显示一个条目。否则,使用多继承的类及其后代将出现多次。

inspect.getargspec(func)

获取Python函数参数的名称和默认值。named tuple ArgSpec(args, varargs, keywords, defaults) t6 >args是参数名称的列表。varargs关键字***参数或Nonedefaults是默认参数值的元组,如果没有默认参数,则为None;如果该元组具有n元素,则它们对应于args中列出的最后一个n元素。

自3.0版起已弃用:使用signature()Signature Object,可为可调用项提供更好的内省API。

inspect.getfullargspec(func)

获取Python函数参数的名称和默认值。返回named tuple

FullArgSpec(args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, 注意)

args是参数名称的列表。varargsvarkw***参数或Nonedefaults是最后一个n参数的默认值的n元组,或None默认参数。kwonlyargs是仅包含关键字的参数名称的列表。kwonlydefaults是将名称从kwonlyargs映射到默认值的字典。注解是将参数名称映射到注释的字典。

元组中的前四个项对应于getargspec()

在版本3.4中更改:此函数现在基于signature(),但仍忽略__wrapped__属性,并包含已绑定的第一个参数绑定方法的声明输出。

自版本3.5后已弃用:使用signature()Signature Object,可为可调用项提供更好的内省API。

inspect.getargvalues(frame)

获取传递到特定框架中的参数的信息。named tuple ArgInfo(args, varargs, 关键字, 本地) t6 >args是参数名称的列表。varargs关键字***参数或Nonelocals是给定框架的本地字典。

自版本3.5后已弃用:使用signature()Signature Object,可为可调用项提供更好的内省API。

inspect.formatargspec(args[, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, annotations[, formatarg, formatvarargs, formatvarkw, formatvalue, formatreturns, formatannotations]])

根据getargspec()getfullargspec()返回的值设置一个漂亮的参数spec。

前七个参数是(argsvarargsvarkwdefaultskwonlyargskwonlydefaultsannotations)。

其他六个参数是被调用来分别将参数名称,*参数名称,**参数名称,默认值,返回注解和单个注解转换为字符串的函数。

例如:

>>> from inspect import formatargspec, getfullargspec
>>> def f(a: int, b: float):
...     pass
...
>>> formatargspec(*getfullargspec(f))
'(a: int, b: float)'

自版本3.5后已弃用:使用signature()Signature Object,可为可调用项提供更好的内省API。

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

根据getargvalues()返回的四个值设置一个漂亮的参数规范。format *参数是相应的可选格式化函数,它们将名称和值转换为字符串。

自版本3.5后已弃用:使用signature()Signature Object,可为可调用项提供更好的内省API。

inspect.getmro(cls)

在方法解析顺序中返回类cls的基类的一个元组,包括cls。没有类在此元组中多次出现。请注意,方法解析顺序取决于cls的类型。除非使用非常特殊的用户定义元类型,否则cls将是元组的第一个元素。

inspect.getcallargs(func, *args, **kwds)

argskwds绑定到Python函数或方法func的参数名称,就好像它们被调用一样。对于绑定方法,还将第一个参数(通常命名为self)绑定到关联的实例。返回一个dict,将参数名称(包括***参数的名称)映射到来自argskwds如果调用func不正确,即每当func(* args, ** kwds)会引发异常,因为声明不相容,同一类型和相同的异常类似的消息被提出。例如:

>>> from inspect import getcallargs
>>> def f(a, b=1, *pos, **named):
...     pass
>>> getcallargs(f, 1, 2, 3) == {'a': 1, 'named': {}, 'b': 2, 'pos': (3,)}
True
>>> getcallargs(f, a=2, x=4) == {'a': 2, 'named': {'x': 4}, 'b': 1, 'pos': ()}
True
>>> getcallargs(f)
Traceback (most recent call last):
...
TypeError: f() missing 1 required positional argument: 'a'

版本3.2中的新功能。

自版本3.5后已弃用:改用Signature.bind()Signature.bind_partial()

inspect.getclosurevars(func)

获取Python函数或方法(func)中外部名称引用的映射到其当前值。named tuple ClosureVars(非本地, 全局, 内置, 未绑定) t6 >非本地将引用名称映射到词法闭包变量,将全局变量映射到函数的模块全局变量,将内置函数映射到从函数主体可见的内置函数。unbound是在函数中引用的名称集合,无法在当前模块全局变量和内置函数下解析。

如果func不是Python函数或方法,则会引发TypeError

版本3.3中的新功能。

inspect.unwrap(func, *, stop=None)

获取由func包装的对象。它遵循返回链中最后一个对象的__wrapped__属性链。

stop是一个可选的回调,它接受包装器链中的一个对象作为其唯一的参数,如果回调返回一个真值,则允许解包被提前终止。如果回调从未返回真值,则链中的最后一个对象将照常返回。例如,signature()如果链中的任何对象定义了__signature__属性,则使用它停止解开。

如果遇到循环,则会引发ValueError

版本3.4中的新功能。

29.12.5. The interpreter stack

当以下函数返回“框架记录”时,每个记录都是named tuple FrameInfo(frame, filename, lineno , 函数, code_context, 索引)元组包含框架对象,文件名,当前行的行号,函数名称,源代码的上下文列表以及该列表中当前行的索引。

在版本3.5中更改:返回命名的元组,而不是元组。

注意

保持对框架对象的引用,如在框架的第一个元素中发现的,记录这些函数返回,可以导致程序创建引用循环。一旦创建了引用循环,即使Python的可选循环检测器被启用,可以从形成循环的对象访问的所有对象的生命周期可能变得更长。如果必须创建这样的循环,则重要的是确保它们被明确地断开以避免对象的延迟破坏和增加的发生的存储器消耗。

虽然循环检测器将捕获这些,但是可以通过去除finally子句中的循环来确定帧(和局部变量)的破坏。如果循环检测器在编译Python或使用gc.disable()时被禁用,这也很重要。例如:

def handle_stackframe_without_leak():
    frame = inspect.currentframe()
    try:
        # do something with the frame
    finally:
        del frame

如果要保留框架(例如稍后打印traceback),还可以使用frame.clear()方法来中断引用循环。

大多数这些函数支持的可选上下文参数指定要返回的上下文的行数,它们以当前行为中心。

inspect.getframeinfo(frame, context=1)

获取有关框架或跟踪对象的信息。named tuple Traceback(filename, lineno, function, code_context, t6 > index)

inspect.getouterframes(frame, context=1)

获取框架和所有外框的框架记录列表。这些框架表示导致创建框架的调用。返回列表中的第一个条目表示框架;最后一个条目表示框架的最外层调用。

Changed in version 3.5: A list of named tuples FrameInfo(frame, filename, lineno, function, code_context, index) is returned.

inspect.getinnerframes(traceback, context=1)

获取traceback的框架和所有内框架的框架记录列表。这些框架表示由框架所产生的调用。列表中的第一个条目表示traceback;最后一个条目表示引发异常的位置。

Changed in version 3.5: A list of named tuples FrameInfo(frame, filename, lineno, function, code_context, index) is returned.

inspect.currentframe()

返回当前调用者的堆栈框架的框架对象。

CPython实现细节:此函数依赖于解释器中的Python栈框架支持,这不能保证在Python的所有实现中都存在。如果在没有Python堆栈的实现中运行,框架支持此函数返回None

inspect.stack(context=1)

返回调用者堆栈的框架记录列表。返回列表中的第一个条目表示调用者;最后一个条目表示堆栈上的最外层调用。

Changed in version 3.5: A list of named tuples FrameInfo(frame, filename, lineno, function, code_context, index) is returned.

inspect.trace(context=1)

返回当前框架和当前正在处理的异常所在的框架之间的堆栈的框架记录列表。列表中的第一个条目表示调用者;最后一个条目表示引发异常的位置。

Changed in version 3.5: A list of named tuples FrameInfo(frame, filename, lineno, function, code_context, index) is returned.

29.12.6. Fetching attributes statically

当提取或检查属性的存在时,getattr()hasattr()都可以触发代码执行。将调用类似属性的描述器,并且可以调用__getattr__()__getattribute__()

对于需要被动内省的情况,如文档工具,这可能不方便。getattr_static()getattr()具有相同的声明,但避免在提取属性时执行代码。

inspect.getattr_static(obj, attr, default=None)

通过描述器协议__getattr__()__getattribute__()检索属性而不触发动态查找。

注意:此函数可能无法检索getattr可以获取的所有属性(如动态创建的属性),并且可能找到getattr不能引用的属性(如引发AttributeError的描述器)。它也可以返回描述器对象而不是实例成员。

如果实例__dict__被另一个成员(例如属性)遮住,那么此函数将无法找到实例成员。

版本3.2中的新功能。

getattr_static()不会解析描述器,例如slot描述器或getset描述器对在C上实现的对象。返回描述器对象而不是底层属性。

你可以用下面的代码处理这些。注意对于任意getset描述器调用这些可能触发代码执行:

# example code for resolving the builtin descriptor types
class _foo:
    __slots__ = ['foo']

slot_descriptor = type(_foo.foo)
getset_descriptor = type(type(open(__file__)).name)
wrapper_descriptor = type(str.__dict__['__add__'])
descriptor_types = (slot_descriptor, getset_descriptor, wrapper_descriptor)

result = getattr_static(some_object, 'foo')
if type(result) in descriptor_types:
    try:
        result = result.__get__()
    except AttributeError:
        # descriptors can raise AttributeError to
        # indicate there is no underlying value
        # in which case the descriptor itself will
        # have to do
        pass

29.12.7. Current State of Generators and Coroutines

当实现协调调度程序和生成器的其他高级使用时,确定生成器当前是否正在执行,正在等待启动或恢复或执行,或已经终止是有用的。getgeneratorstate()允许容易地确定生成器的当前状态。

inspect.getgeneratorstate(generator)

获取生成器迭代器的当前状态。

可能的状态是:
  • GEN_CREATED:正在等待开始执行。
  • GEN_RUNNING:当前正由解释器执行。
  • GEN_SUSPENDED:目前暂停在yield表达式。
  • GEN_CLOSED:执行已完成。

版本3.2中的新功能。

inspect.getcoroutinestate(coroutine)

获取协程对象的当前状态。该函数旨在与由async def函数创建的协程对象一起使用,但将接受任何具有cr_runningcr_frame属性。

可能的状态是:
  • CORO_CREATED:正在等待开始执行。
  • CORO_RUNNING:当前由解释器执行。
  • CORO_SUSPENDED:目前暂停等待表达。
  • CORO_CLOSED:执行已完成。

版本3.5中的新功能。

也可以查询生成器的当前内部状态。这主要用于测试目的,以确保内部状态正在按预期更新:

inspect.getgeneratorlocals(generator)

获取生成器中的实时局部变量到其当前值的映射。返回从变量名映射到值的字典。这相当于在生成器的主体中调用locals(),所有相同的注意事项都适用。

如果生成器是没有当前关联框架的generator,则返回空字典。如果生成器不是Python生成器对象,则会引发TypeError

CPython实现细节:此函数依赖于生成器公开一个Python堆栈框架以进行内省,这不能保证在所有Python实现中都是这样。在这种情况下,此函数将始终返回一个空字典。

版本3.3中的新功能。

inspect.getcoroutinelocals(coroutine)

此函数类似于getgeneratorlocals(),但适用于由async def函数创建的协程对象。

版本3.5中的新功能。

29.12.8. Command Line Interface

inspect模块还从命令行提供了基本的自省功能。

默认情况下,接受模块的名称并打印该模块的源。可以通过附加冒号和目标对象的限定名称来打印模块中的类或函数。

--details

打印有关指定对象而不是源代码的信息