Python(inspect)



inspect 模块是 Python 标准库中的一个强大工具,用于获取有关 Python 对象(类、函数、模块等)的信息。它可以帮助开发者在运行时检查代码结构、提取源代码、分析参数签名、检查继承关系,甚至进行动态 introspection(自省)。



1. inspect 模块的主要功能

1.1 获取对象的信息

  • inspect.getmembers(object, predicate=None): 获取对象的所有成员(包括方法、属性等)。
  • inspect.getmodule(object): 获取定义某个对象的模块。
  • inspect.getdoc(object): 获取对象的文档字符串(docstring)。
  • inspect.getfile(object): 获取对象的源文件路径。
  • inspect.getsource(object): 获取对象的源代码。
  • inspect.getsourcefile(object): 获取源代码文件路径(如果可用)。
  • inspect.getsourcelines(object): 获取对象的源代码及起始行号。

示例

import inspect
import math

print(inspect.getmodule(math.sin))  # 输出: <module 'math' (built-in)>
print(inspect.getdoc(math.sin))     # 输出: Return the sine of x (measured in radians).
print(inspect.getfile(math))        # 输出: /path/to/python/lib/python3.x/math.py


1.2 检查对象的类型

  • inspect.ismodule(object): 判断对象是否是模块。
  • inspect.isclass(object): 判断对象是否是类。
  • inspect.isfunction(object): 判断对象是否是函数。
  • inspect.ismethod(object): 判断对象是否是方法。
  • inspect.isbuiltin(object): 判断对象是否是内置函数。
  • inspect.isroutine(object): 判断对象是否是可调用(函数、方法等)。

示例

import inspect
import math

print(inspect.isfunction(math.sin))  # False(math.sin 是内置函数)
print(inspect.isbuiltin(math.sin))   # True
print(inspect.ismodule(math))        # True


1.3 获取函数或类的签名信息

  • inspect.signature(callable): 获取函数/方法的参数信息。
  • inspect.getfullargspec(callable): 获取完整参数信息(Python 3.0+ 被 inspect.signature() 取代)。
  • inspect.getcallargs(callable, *args, **kwargs): 解析函数调用时的参数。

示例

import inspect

def example_func(a, b: int = 10, *args, c=20, **kwargs):
    pass

sig = inspect.signature(example_func)
for name, param in sig.parameters.items():
    print(f"参数名: {name}, 类型: {param.kind}, 默认值: {param.default}")

# 解析调用参数
args_values = inspect.getcallargs(example_func, 1, 2, 3, c=30, d=40)
print(args_values)

输出

参数名: a, 类型: POSITIONAL_OR_KEYWORD, 默认值: <class 'inspect._empty'>
参数名: b, 类型: POSITIONAL_OR_KEYWORD, 默认值: 10
参数名: args, 类型: VAR_POSITIONAL, 默认值: <class 'inspect._empty'>
参数名: c, 类型: KEYWORD_ONLY, 默认值: 20
参数名: kwargs, 类型: VAR_KEYWORD, 默认值: <class 'inspect._empty'>
{'a': 1, 'b': 2, 'args': (3,), 'c': 30, 'kwargs': {'d': 40}}


1.4 获取类的继承关系

  • inspect.getmro(class): 获取类的 MRO(方法解析顺序)。
  • inspect.getclasstree(classes, unique=False): 获取类的继承层次结构。

示例

import inspect

class A: pass
class B(A): pass
class C(B): pass

print(inspect.getmro(C))  # 输出: (<class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>)

1.5 动态调用与绑定

  • inspect.isgeneratorfunction(func): 判断是否为生成器函数。
  • inspect.iscoroutinefunction(func): 判断是否为协程函数(async def)。
  • inspect.getclosurevars(func): 获取闭包变量。
  • inspect.currentframe(): 获取当前调用栈帧。

示例

import inspect

def outer(x):
    y = 10
    def inner():
        return x + y
    return inner

closure_vars = inspect.getclosurevars(outer(5))
print(closure_vars)  # 输出: ClosureVars(nonlocals={'x': 5, 'y': 10}, globals={}, builtins={}, unbound=[])


2. inspect 在调试和反射中的应用

2.1 获取调用栈

  • inspect.stack(): 获取当前调用栈的详细信息,适用于调试和日志记录。

示例

import inspect

def func():
    stack = inspect.stack()
    for frame in stack:
        print(f"文件: {frame.filename}, 行号: {frame.lineno}, 函数: {frame.function}")

def main():
    func()

main()

2.2 动态调用函数

可以结合 inspect.signature()getcallargs() 实现通用的动态调用:

import inspect

def add(x, y=10):
    return x + y

def dynamic_call(func, *args, **kwargs):
    bound_args = inspect.signature(func).bind(*args, **kwargs)
    bound_args.apply_defaults()
    return func(*bound_args.args, **bound_args.kwargs)

print(dynamic_call(add, 5))        # 15
print(dynamic_call(add, 5, y=20))  # 25


3. 总结

功能 方法
获取对象信息 getmembers(), getmodule(), getdoc(), getsource()
检查对象类型 ismodule(), isclass(), isfunction(), ismethod()
函数参数信息 signature(), getfullargspec(), getcallargs()
类继承关系 getmro(), getclasstree()
动态绑定 isgeneratorfunction(), iscoroutinefunction()
获取调用栈 stack(), currentframe()

inspect 模块是 Python 反射和动态 introspection 的核心工具之一,在调试、代码分析、动态调用等场景下非常有用。



posted @ 2025-03-03 15:42  做梦当财神  阅读(94)  评论(0)    收藏  举报