Python进阶之-inspect模块详解

✨前言:

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 inspect


def foo(a, *, b: int, **kwargs):
    pass


sig = 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 inspect


class DemoClass:
    def demo_method(self):
        pass


print(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 = 1

    def my_method(self):
        pass


members = inspect.getmembers(MyClass, predicate=inspect.isfunction)
print(members)  # 输出类中所有函数成员

✨5. 获取类的继承关系:

inspect.getmro(cls): 返回一个元组,包含cls类的基类,按照方法解析顺序。

import inspect


class BaseClass:
    pass


class DerivedClass(BaseClass):
    pass

print(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 inspect


def 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文档生成以及理解代码的结构和行为。

  • 22
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夏天Aileft

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值