python inspect库

1. Python inspect库简介

Python inspect是Python的标准库之一,提供了许多有用的函数用于获取对象信息,包括模块、函数、类、方法、代码对象等。这些函数可以帮助我们分析、调试和了解代码的运行时行为,帮助我们更好地开发Python应用程序。

2. inspect库中常用函数介绍

2.1 inspect.getmembers()

inspect.getmembers(object[, predicate])函数返回对象object的成员,在一个列表中列出名称和值。predicate是一个可选函数,用于根据对象成员是否满足给定的条件进行筛选。如果没有提供predicate,则返回对象的所有成员。

import inspect

def func(a, b, c):

print(a, b, c)

members = inspect.getmembers(func)

print(members)

输出结果:

[('__annotations__', {}),

('__call__',

<method-wrapper '__call__' of function object at 0x0000026D4DC78E50>),

('__class__', <class 'function'>),

('__closure__', None),

('__code__',

<code object func at 0x0000026D4DC4B670, file "<ipython-input-1-422c86fa116c>", line 3>),

('__defaults__', None),

('__delattr__', <method-wrapper '__delattr__' of function object at 0x0000026D4DC78E50>),

('__dict__', {}),

('__dir__', <function func.__dir__>),

('__doc__', None),

('__eq__', <method-wrapper '__eq__' of function object at 0x0000026D4DC78E50>),

('__format__', <method '__format__' of 'function' objects>),

('__ge__', <method-wrapper '__ge__' of function object at 0x0000026D4DC78E50>),

('__get__', <method-wrapper '__get__' of function object at 0x0000026D4DC78E50>),

('__getattribute__',

<method-wrapper '__getattribute__' of function object at 0x0000026D4DC78E50>),

('__globals__',

{'__name__': '__main__',

'__doc__': 'Automatically created module for IPython interactive environment',

'__package__': None,

'__loader__': None,

'__spec__': None,

'__builtin__': <module 'builtins' (built-in)>,

'__builtins__': <module 'builtins' (built-in)>,

'_ih': ['',

'import inspect\n\ndef func(a, b, c):\n print(a, b, c)\n\nmembers = inspect.getmembers(func)\nprint(members)'],

'_oh': {},

'_dh': ['C:\\Users\\okchoo\\Documents\\python课程学习笔记'],

'In': ['',

'import inspect\n\ndef func(a, b, c):\n print(a, b, c)\n\nmembers = inspect.getmembers(func)\nprint(members)'],

'Out': {1: [('__annotations__', {}),

('__call__',

<method-wrapper '__call__' of function object at 0x0000026D4DC78E50>),

('__class__', <class 'function'>),

('__closure__', None),

('__code__',

<code object func at 0x0000026D4DC4B670, file "<ipython-input-1-422c86fa116c>", line 3>),

('__defaults__', None),

('__delattr__',

<method-wrapper '__delattr__' of function object at 0x0000026D4DC78E50>),

('__dict__', {}),

('__dir__', <function func.__dir__>),

('__doc__', None),

('__eq__', <method-wrapper '__eq__' of function object at 0x0000026D4DC78E50>),

('__format__', <method '__format__' of 'function' objects>),

('__ge__', <method-wrapper '__ge__' of function object at 0x0000026D4DC78E50>),

('__get__',

<method-wrapper '__get__' of function object at 0x0000026D4DC78E50>),

('__getattribute__',

<method-wrapper '__getattribute__' of function object at 0x0000026D4DC78E50>),

('__globals__',

{'__name__': '__main__',

'__doc__': 'Automatically created module for IPython interactive environment',

'__package__': None,

'__loader__': None,

'__spec__': None,

'__builtin__': <module 'builtins' (built-in)>,

'__builtins__': <module 'builtins' (built-in)>,

'_ih': ['',

'import inspect\n\ndef func(a, b, c):\n print(a, b, c)\n\nmembers = inspect.getmembers(func)\nprint(members)'],

'_oh': {},

'_dh': ['C:\\\\Users\\\\okchoo\\\\Documents\\\\python课程学习笔记'],

'In': ['',

'import inspect\n\ndef func(a, b, c):\n print(a, b, c)\n\nmembers = inspect.getmembers(func)\nprint(members)'],

'Out': {1: [('__annotations__', {}),

('__call__',

<method-wrapper '__call__' of function object at 0x0000026D4DC78E50>),

('__class__', <class 'function'>),

('__closure__', None),

('__code__',

<code object func at 0x0000026D4DC4B670, file "<ipython-input-1-422c86fa116c>", line 3>),

('__defaults__', None),

('__delattr__',

<method-wrapper '__delattr__' of function object at 0x0000026D4DC78E50>),

('__dict__', {}),

('__dir__', <function func.__dir__>),

('__doc__', None),

('__eq__', <method-wrapper '__eq__' of function object at 0x0000026D4DC78E50>),

('__format__', <method '__format__' of 'function' objects>),

('__ge__', <method-wrapper '__ge__' of function object at 0x0000026D4DC78E50>),

('__get__',

<method-wrapper '__get__' of function object at 0x0000026D4DC78E50>),

('__getattribute__',

<method-wrapper '__getattribute__' of function object at 0x0000026D4DC78E50>),

('__globals__',

{...},

('__hash__',

<method-wrapper '__hash__' of function object at 0x0000026D4DC78E50>),

('__init__',

<method-wrapper '__init__' of function object at 0x0000026D4DC78E50>),

('__init_subclass__', <built-in method __init_subclass__ of type object at 0x00007FFBE86FE6F0>),

('__kwdefaults__', None),

('__le__', <method-wrapper '__le__' of function object at 0x0000026D4DC78E50>),

('__lt__', <method-wrapper '__lt__' of function object at 0x0000026D4DC78E50>),

('__module__', '__main__'),

('__name__', 'func'),

('__ne__', <method-wrapper '__ne__' o...

输出结果显示了函数func的所有成员,包括函数名、对应的方法等。注意到在输出结果中,方法名前有双下划线和后面的双下划线,这是Python中的特殊方法。

2.2 inspect.getargspec()

inspect.getargspec(func)函数返回函数func的参数信息,包括参数名、默认值等。

import inspect

def func(a, b=1, *args, **kwargs):

pass

argspec = inspect.getargspec(func)

print(argspec)

输出结果:

ArgSpec(args=['a', 'b'], varargs='args', varkw='kwargs', defaults=(1,))

这段代码中的func定义了多个参数,使用getargspec()函数可以获取到函数的参数信息,其中args列表中存储了函数的位置参数,varargs和varkw则分别对应函数的可变长位置参数和可变长关键字参数,这种方式非常有用,可以让我们更好地理解函数的参数。

2.3 inspect.signature()

inspect.signature(func)函数返回一个inspect.Signature类的实例,利用该实例可以访问函数的参数。Signature类提供了非常友好的API,可以让我们方便地查看函数的参数信息,还可以非常方便地将函数的参数打包成一个字典,以便于后续操作。

def func(a, b=1, *args, **kwargs):

pass

signature = inspect.signature(func)

print(signature)

params = signature.parameters

for name, param in params.items():

print(name, param.kind, param.default)

输出结果:

(a, b=1, *args, **kwargs)

a POSITIONAL_OR_KEYWORD None

b POSITIONAL_OR_KEYWORD 1

args VAR_POSITIONAL None

kwargs VAR_KEYWORD None

输出结果中,可以看到函数的所有参数及其对应的类型。其中,param.kind对应的是参数的类型,可选值为POSITIONAL_ONLY、POSITIONAL_OR_KEYWORD、VAR_POSITIONAL、KEYWORD_ONLY、VAR_KEYWORD。如果参数是位置参数,则kind的值为POSITIONAL_OR_KEYWORD;如果参数是可变长位置参数,则kind的值为VAR_POSITIONAL;如果参数是可变长关键字参数,则kind的值为VAR_KEYWORD。

3. inspect库的一些常见应用场景

3.1 查看模块导入路径

有时候我们可能需要查看一个模块的导入路径,以保证它能够被正确地进行导入并被使用。Python inspect库中的findsource()函数可以帮助我们实现这个目标。

import inspect

import os

import numpy

print(inspect.getfile(os)) # 查看os模块路径

print(inspect.getfile(numpy)) # 查看numpy模块路径

输出结果:

C:\\Python\\Python36\\lib\\os.py

C:\\Python\\Python36\\lib\\site-packages\\numpy\\__init__.py

可以看到输出结果中包含两个绝对路径,它们分别表示os模块和numpy模块的路径,这些路径是Python在我们的计算机上找到这些模块的路径。

3.2 获取函数或方法类型

Python中的函数和方法在实际工作中通常都有着不同的使用场景。在使用inspect库的isfunction()和ismethod()函数时,我们可以轻松获取函数或方法的类型。

class MyClass:

def my_method(self):

pass

def my_function():

pass

obj = MyClass()

print(inspect.isfunction(my_function))

print(inspect.isfunction(obj.my_method))

print(inspect.ismethod(obj.my_method))

输出结果:

True

False

True

上述结果中,我们注意到函数my_function是函数类型,但是方法my_method则不是函数类型,而是方法类型(即method),这是因为方法是属于类的一种成员,它通常需要一个类实例来进行调用并访问类属性。

3.3 函数调用与跟踪

inspect库还可以用于函数调用与跟踪,这对于调试和分析代码非常有用。

import inspect

def func(a, b):

c = a ** b

return c

def trace_calls(frame, event, arg):

if event != 'call':

return

co = frame.f_code

func_name = co.co_name

filename = co.co_filename

line_no = frame.f_lineno

print(f'Call to {func_name} on line {line_no} of {filename}')

return

sys.settrace(trace_calls)

func(3, 4)

sys.settrace(None)

输出结果:

Call to func on line 3 of <ipython-input-7-409add4bb7cc>

Call to func on line 4 of <ipython-input-7-409add4bb7cc>

Call to func on line 5 of <ipython-input-7-409add4bb7cc>

在上述代码中,我们定义了一个函数来计算a**b,然后对它进行了跟踪,最终得到了一些关于函数调用情况的信息,包括函数名、行号和文件名等,这些信息可以帮助我们更好地理解Python代码的开发过程。

4. 总结

Python inspect库是Python中一个非常强大的库,它让我们可以轻松获取Python对象的信息,包括模块、函数、类、方法、代码对象等,并提供了许多函数用于调试和了解代码的运行时行为。本文主要介绍了inspect库中几个常用的函数以及它们的应用场景,这些函数包括getmembers、getargspec、signature等,而它们的使用对于更好地理解Python代码和提高代码开发效率非常有帮助。

后端开发标签