29.12. inspect - 检查活动对象

源程序代码︰Lib/inspect.py

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

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

29.12.1. 类型和成员

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

类型属性描述
module__doc__文档字符串
__file__文件名(内置模块缺失)
class__doc__文档字符串
__name__这个类被定义的名称
__qualname__限定名称
__module__在这个类中定义的模块的名称
method__doc__文档字符串
__name__这个方法被定义的名称
__qualname__限定名称
__func__包含方法实现的函数对象
__self__该方法绑定到的实例,或None
function__doc__文档字符串
__name__这个函数被定义的名字
__qualname__限定名称
__code__包含编译函数bytecode的代码对象
__defaults__用于位置或关键字参数的任何默认值的元组
__kwdefaults__为关键字参数映射任何默认值
__globals__在其中定义了该函数的全局名称空间
__annotations__mapping of parameters names to annotations; "return" key is reserved for return annotations.
tracebacktb_frame在这个级别的框架对象
tb_lasti字节码中最后一次尝试指令的索引
tb_linenoPython源代码中的当前行号
tb_next下一个内部追踪对象(由此级别调用)
framef_back下一个外框对象(这个框架的调用者)
f_builtins建立了这个框架所看到的名字空间
f_code代码对象在这个框架中被执行
f_globals全局名称空间由此框架看到
f_lasti字节码中最后一次尝试指令的索引
f_linenoPython源代码中的当前行号
f_locals本框架所看到的本地名称空间
f_restricted如果帧处于受限执行模式,则为0或1
f_trace追踪此帧的功能,或None
codeco_argcount参数数量(不包括*或**参数)
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参数名称和局部变量的元组
generator__name__名称
__qualname__限定名称
gi_frame
gi_running发电机正在运转吗?
gi_code
gi_yieldfrom对象由产生 ,或None
coroutine__name__名称
__qualname__限定名称
cr_await对象正在等待,或None
cr_frame
cr_running协程运行?
cr_code
builtin__doc__文档字符串
__name__此功能或方法的原始名称
__qualname__限定名称
__self__绑定方法的实例,或None

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

现在生成器的__ name __属性是根据函数名称中设置的,而不是代码名称,并且可以修改。

inspect.getmembers(object[, predicate])

返回按名称排序的(name, value)列表中的所有成员对象。如果提供了可选的predicate参数,则只包含predicate返回true值的成员。

注意

当参数是一个类时,getmembers()只会返回已定义在元类中的类属性,并且这些属性已经列在元类的自定义__ dir __()中。

inspect.getmoduleinfo(path)

返回一个命名元组 ModuleInfo(name, suffix, mode, module_type)描述Python如何解释由path标识的文件是模块,或者返回None,如果没被标识为模块。In 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)

如果对象是一个类,无论是内置的还是用Python代码创建的,则返回true。

inspect.ismethod(object)

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

inspect.isfunction(object)

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

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)

如果对象是方法描述符,则返回true,但如果ismethod()isclass()isfunction()isbuiltin()是真的。

例如,这对于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中定义),getset和成员。后两种是在C中定义的,并且这些类型有更多特定的测试可用,这在Python实现中是健壮的。通常情况下,数据描述符也将具有__name____doc__属性(属性,getset和成员都具有这两个属性),但不能保证。

inspect.isgetsetdescriptor(object)

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

CPython implementation detail: getsets are attributes defined in extension modules via PyGetSetDef structures. 对于没有这种类型的Python实现,此方法将始终返回False

inspect.ismemberdescriptor(object)

如果对象是成员描述符,则返回true。

CPython implementation detail: Member descriptors are attributes defined in extension modules via PyMemberDef structures. 对于没有这种类型的Python实现,此方法将始终返回False

29.12.2. 检索源代码

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. 使用Signature对象抽象可调式对象

版本3.3中的新功能。

Signature对象表示可调用对象的调用签名及其返回注释。要检索签名对象,请使用signature()函数。

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

为给定的callable返回一个Signature对象:

>>> 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'>

从普通函数和类到functools.partial()对象接受大量的python可调参数。

如果不提供签名,则引发ValueError;如果不支持该类型的对象,则引发TypeError

版本3.5中的新功能: follow_wrapped参数。通过False获得callable的特征(callable.__wrapped__不会用于解开装饰可调用)。

注意

在Python的某些实现中,某些可调用对象可能不是内省的。例如,在CPython中,C中定义的一些内置函数不提供关于它们参数的元数据。

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

Signature对象表示函数的调用签名及其返回注释。对于函数接受的每个参数,它都会在parameters集合中存储Parameter对象。

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

可选的return_annotation参数可以是一个任意的Python对象,是可调用对象的“返回”注释。

签名对象是不可变的使用Signature.replace()进行修改后的副本。

在版本3.5中更改:签名对象是可挑选和可散列的。

empty

一种特殊的级别标记,用于指定缺少返回注释。

parameters

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

return_annotation

可调用的“返回”注释。如果可调用对象没有“返回”注释,则将此属性设置为Signature.empty

bind(*args, **kwargs)

从位置和关键字参数创建一个映射到参数。如果*args**kwargs匹配签名,或者引发TypeError,则返回BoundArguments

bind_partial(*args, **kwargs)

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

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

根据调用的实例替换创建新的Signature实例。可以传递不同的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)

为给定的可调用obj返回一个Signature(或其子类)对象。Pass follow_wrapped=False to get a signature of obj without unwrapping its __wrapped__ chain.

该方法简化了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)

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

在版本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没有绑定到任何其他参数的关键字参数的字典。这对应于Python函数定义中的**kwargs参数。

例如:打印没有默认值的所有关键字参数:

>>> 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. 类和函数

inspect.getclasstree(classes, unique=False)

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

inspect.getargspec(func)

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

从版本3.0开始弃用:使用signature()Signature Object,为可调参数提供更好的内省API。

inspect.getfullargspec(func)

获取Python函数参数的名称和默认值。A named tuple is returned:

FullArgSpec(args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, annotations)

args是参数名称的列表。varargsvarkw***参数的名称或None默认值是最后一个n参数的默认值的n值,或None默认参数。kwonlyargs是关键字参数名称列表。kwonlydefaults是将kwonlyargs中的名称映射为默认值的字典。注释是将参数名称映射到注释的字典。

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

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

从版本3.5开始不推荐使用:使用signature()Signature Object,为可调参数提供更好的内省API。

inspect.getargvalues(frame)

获取有关传递到特定框架的参数的信息。A named tuple ArgInfo(args, varargs, keywords, locals) is returned. args是参数名称的列表。varargs关键字***参数的名称或Nonelocals is the locals dictionary of the given frame.

从版本3.5开始不推荐使用:使用signature()Signature Object,为可调参数提供更好的内省API。

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

根据getargspec()getfullargspec()返回的值格式化漂亮的参数规范。

前七个参数是(argsvarargsvarkwdefaultskwonlyargskwonlydefaultsannotations)。

The other six arguments are functions that are called to turn argument names, * argument name, ** argument name, default values, return annotation and individual annotations into strings, respectively.

例如:

>>> 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()返回的四个值格式化漂亮的参数规范。格式*参数是相应的可选格式函数,被称为将名称和值转换为字符串。

从版本3.5开始不推荐使用:使用signature()Signature Object,为可调参数提供更好的内省API。

inspect.getmro(cls)

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

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

argskwds绑定到Python函数或方法func的参数名称,就好像它们是用它们调用的一样。对于绑定方法,还要将第一个参数(通常名为self)绑定到关联的实例。返回一个字典,将参数名称(包括***参数的名称,如果有的话)映射到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(nonlocals, 全局变量, 内置变量, 未绑定) t6 >返回。nonlocals将引用名称映射到词法封闭变量,将globals映射到函数的模块全局变量,将builtins映射到可从函数体可见的内建变量。unbound是函数中引用的名称集,根据当前的模块全局变量和内建函数,它们根本无法解析。

TypeError is raised if func is not a Python function or method.

版本3.3中的新功能。

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

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

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

ValueError is raised if a cycle is encountered.

版本3.4中的新功能。

29.12.5. 解释器堆栈

When the following functions return “frame records,” each record is a named tuple FrameInfo(frame, filename, lineno, function, code_context, index). 该元组包含框架对象,文件名,当前行的行号,函数名称,源代码中的上下文行列表以及该列表中当前行的索引。

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

注意

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

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

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

如果要保留框架(例如稍后打印回溯),还可以使用frame.clear()方法来中断参考周期。

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

inspect.getframeinfo(frame, context=1)

获取关于帧或追溯对象的信息。A named tuple Traceback(filename, lineno, function, code_context, index) is returned.

inspect.getouterframes(frame, context=1)

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

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;最后一个条目表示引发异常的位置。

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

inspect.currentframe()

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

CPython implementation detail: This function relies on Python stack frame support in the interpreter, which isn’t guaranteed to exist in all implementations of 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. 静态获取属性

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

对于需要被动内省的情况,如文档工具,这可能不方便。getattr_static() has the same signature as getattr() but avoids executing code when it fetches attributes.

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

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

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

如果实例__dict__被另一个成员(例如属性)遮蔽,则该函数将无法找到实例成员。

版本3.2中的新功能。

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

您可以使用如下代码处理这些问题。请注意,对于任意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. 发生器和协程的当前状态

在实现协程调度程序和生成器的其他高级用途时,确定生成器当前是否正在执行,是否正在等待启动或恢复或执行或已经终止会很有用。getgeneratorstate() allows the current state of a generator to be determined easily.

inspect.getgeneratorstate(generator)

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

可能的状态是:
  • GEN_CREATED:等待开始执行。
  • GEN_RUNNING:目前正在由解释器执行。
  • GEN_SUSPENDED:目前暂停在产量表达式。
  • 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)

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

如果generatorgenerator,并且没有当前关联的帧,则返回空字典。TypeError is raised if generator is not a Python generator object.

CPython implementation detail: This function relies on the generator exposing a Python stack frame for introspection, which isn’t guaranteed to be the case in all implementations of Python. 在这种情况下,该函数将始终返回一个空字典。

版本3.3中的新功能。

inspect.getcoroutinelocals(coroutine)

这个函数类似于getgeneratorlocals(),但是对由async def函数创建的协程对象起作用。

版本3.5中的新功能。

29.12.8. 命令行界面

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

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

--details

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