✨前言:
Python中的inspect模块是用于获取对象的信息的模块,比如查看源代码、列出成员、检查类和函数的参数等,非常适用于调试和反射(introspection)。接下来,我会详细解释inspect模块,并结合例子说明一些常用的方法。
inspect 模块的主要功能包括:
获取对象信息:可以获取对象的类型、名称、模块、源代码等信息。
获取函数和方法的参数信息:可以获取函数或方法的参数列表、默认参数值、注解等信息。
获取类的继承关系和属性信息:可以获取类的基类、方法、属性等信息。 检查对象的属性和成员:可以检查对象是否具有某个属性或成员,并获取属性的值。
检查代码对象的源代码:可以获取函数、类、方法等对象的源代码。 inspect
模块在许多情况下非常有用,特别是在编写装饰器、元类和调试工具时。它提供了一种方便的方式来检查和操作代码对象,使开发者能够更好地理解和处理运行时的对象。
✨1. 查看源代码:
inspect.getsource(object): 返回对象的源代码。对于函数、类、方法或模块等,此方法返回其源代码字符串。
import inspect# 获取函数的源码
def demo_func():print("Hello, world!")print(inspect.getsource(demo_func))
✨2. 获取类或函数的参数信息:
inspect.signature(callable): 返回一个Signature对象,代表可调用对象的签名信息(参数信息)。
import inspectdef foo(a, *, b: int, **kwargs):passsig = inspect.signature(foo)
print(sig) # 输出: (a, *, b:int, **kwargs)
print(sig.parameters['b']) # 输出:b:int
✨3. 判断对象类型:
inspect.isfunction(object): 检查对象是否是函数。
inspect.isclass(object): 检查对象是否是类。
inspect.ismethod(object): 检查对象是否是绑定到类的方法。
import inspectclass DemoClass:def demo_method(self):passprint(inspect.isfunction(DemoClass)) # False
print(inspect.isclass(DemoClass)) # True
print(inspect.ismethod(DemoClass().demo_method)) # True
✨4. 获取模块或类的成员:
inspect.getmembers(object, [predicate]): 返回对象的成员列表。predicate是一个可选的函数,用来过滤返回的成员。
import inspect
import math# 获取math模块中所有成员
members = inspect.getmembers(math)
for name, value in members:print(name, value)# 获取类成员
class MyClass:def __init__(self):self.a = 1def my_method(self):passmembers = inspect.getmembers(MyClass, predicate=inspect.isfunction)
print(members) # 输出类中所有函数成员
✨5. 获取类的继承关系:
inspect.getmro(cls): 返回一个元组,包含cls类的基类,按照方法解析顺序。
import inspectclass BaseClass:passclass DerivedClass(BaseClass):passprint(inspect.getmro(DerivedClass))
# 输出: (<class '__main__.DerivedClass'>, <class '__main__.BaseClass'>, <class 'object'>)
✨其他:
inspect的强大远不止于此,另外inspect还有很多使用方法,有兴趣的同学可以看inspect的源码,下面提供一些常用的。
🌟方法和属性的检查
inspect.ismodule(object): 检查对象是否是一个模块。
inspect.ismethoddescriptor(object): 检查对象是否是方法描述符。
inspect.isdatadescriptor(object): 检查对象是否是数据描述符。
inspect.isgeneratorfunction(object): 检查对象是否是生成器函数。
inspect.isgenerator(object): 检查对象是否是生成器。
inspect.iscoroutinefunction(object): 检查对象是否是协程函数。
inspect.iscoroutine(object): 检查对象是否是协程。
inspect.isasyncgenfunction(object): 检查对象是否是异步生成器函数。
inspect.isasyncgen(object): 检查对象是否是异步生成器。
inspect.isroutine(object): 检查对象是否是用户定义或内建的函数或方法。
🌟检查调用堆栈
inspect.stack(): 返回调用堆栈的帧记录列表,每个帧记录包含帧对象、文件名、行号、函数名、源代码行列表以及索引指向源代码行的列表。
inspect.currentframe(): 返回当前线程的当前帧对象。
inspect.getouterframes(frame, context=1): 获取帧对象的外部帧记录列表,context指定周围源代码行数。
inspect.getinnerframes(traceback, context=1): 获取traceback对象的内部帧记录列表。
🌟其他实用工具
inspect.getdoc(object): 获取对象的文档字符串。
inspect.getcomments(object): 获取对象的注释字符串。
inspect.getfile(object): 获取定义对象的文件名。
inspect.getmodule(object): 获取定义对象的模块。
inspect.getsourcefile(object): 获取定义对象的源码文件名。
inspect.getsourcelines(object): 获取对象的源码行。
inspect.getlineno(object): 获取对象定义的行号。
inspect.getclasstree(classes, unique=False): 获取类的继承树。
inspect.indent(s): 根据对象的嵌套层级添加缩进。
示例:使用inspect.stack()
import inspectdef grandparent():parent()def parent():child()def child():for frame_record in inspect.stack():caller_frame = frame_record[0]info = inspect.getframeinfo(caller_frame)print(f"Function '{info.function}' called at line {info.lineno} of file {info.filename}")grandparent()
这个示例将演示如何使用inspect.stack()跟踪函数调用堆栈,并获取每一帧调用的信息,如函数名、文件名和行号。
inspect模块极大地提升了Python代码反射的能力,有助于调试、API文档生成以及理解代码的结构和行为。