
本文详解如何利用 inspect 模块(如 inspect.getmembers()、inspect.isfunction()、inspect.ismethod() 等)系统性地提取模块中类的全部属性(含类变量、实例变量、方法)、函数定义及元信息,避免遗漏内置属性或误判可调用对象。
本文详解如何利用 `inspect` 模块(如 `inspect.getmembers()`、`inspect.isfunction()`、`inspect.ismethod()` 等)系统性地提取模块中类的全部属性(含类变量、实例变量、方法)、函数定义及元信息,避免遗漏内置属性或误判可调用对象。
在 Python 开发中,动态分析模块结构(如自动文档生成、测试框架反射、插件系统元编程)常需精确识别类与函数的成员构成。inspect 模块是标准库中最强大、最可靠的反射工具集。仅靠 dir() 会混入大量内置属性且无法区分类型;而 inspect.getmembers() 结合谓词函数(predicate)可实现精准筛选。
✅ 获取类的所有非方法属性(类变量、实例变量等)
import my_file as mf
import inspect
# 获取 Attack 类本身(非实例),用于提取类级属性
AttackClass = mf.Attack
# 获取所有非可调用成员(即排除方法、函数等)
attributes = inspect.getmembers(AttackClass, lambda x: not inspect.isroutine(x))
# 过滤掉以双下划线开头的特殊属性(可选)
filtered_attrs = [(name, val) for name, val in attributes if not name.startswith('__')]
print("Non-method attributes (class-level):")
for name, val in filtered_attrs:
print(f" {name} = {repr(val)}")
输出:
Non-method attributes (class-level): ss = 741
⚠️ 注意:ss = 741 是类变量,属于 Attack 类本身;若在 __init__ 中定义 self.xxx,则需通过实例(如 mf.Attack())才能访问该实例属性——但当前示例中无 __init__,故无实例变量。
✅ 区分方法、静态方法、类方法与普通函数
# 获取所有可调用成员,并分类识别
members = inspect.getmembers(AttackClass, inspect.isroutine)
methods = []
statics = []
classes = []
for name, obj in members:
if isinstance(obj, staticmethod):
statics.append(name)
elif isinstance(obj, classmethod):
classes.append(name)
else:
# 检查是否为绑定方法(需结合 __func__ 或 inspect.signature 判断)
if hasattr(obj, '__func__'): # 可能是未绑定方法(Python 3.10+ 更推荐 inspect.isfunction + ismethod 组合)
methods.append(name)
else:
methods.append(name)
print(f"Regular methods: {methods}") # ['the_function']
print(f"Static methods: {statics}") # []
print(f"Class methods: {classes}") # []
✅ 同时提取模块中所有函数与类(完整扫描模板)
def analyze_module(module):
print(f"\n=== Analyzing module '{module.__name__}' ===\n")
# 1. 所有类
classes = [name for name, obj in inspect.getmembers(module, inspect.isclass)]
print(f"Classes: {classes}")
# 2. 所有函数(顶层函数,非类内方法)
functions = [name for name, obj in inspect.getmembers(module, inspect.isfunction)]
print(f"Top-level functions: {functions}")
# 3. 遍历每个类,分别列出其属性与方法
for cls_name in classes:
cls = getattr(module, cls_name)
print(f"\n--- Class '{cls_name}' ---")
# 类变量 & 实例变量(静态属性)
attrs = inspect.getmembers(cls, lambda x: not inspect.isroutine(x))
public_attrs = [(n, v) for n, v in attrs if not n.startswith('__')]
print(f"Public attributes: {public_attrs}")
# 方法(含绑定/未绑定)
methods = inspect.getmembers(cls, inspect.isfunction)
print(f"Declared methods (via isfunction): {[m[0] for m in methods]}")
# 使用示例
analyze_module(mf)
? 关键要点总结
- inspect.getmembers(obj, predicate) 是核心接口,比 dir() 更语义化、更可控;
- inspect.isroutine() 匹配所有可调用对象(函数、方法、lambda、builtin 等),反向使用(not inspect.isroutine)适合提取数据属性;
- 类变量(如 ss = 741)属于类对象自身,直接传入 mf.Attack 即可获取;实例变量需先创建实例再检查其 __dict__;
- inspect.isfunction 仅匹配普通函数(包括类内定义的 def 方法,但此时它仍是函数对象);inspect.ismethod 仅匹配已绑定的方法(如 obj.method),对类本身调用 getmembers(..., ismethod) 将返回空;
- 如需深度分析(如参数签名、源码行号、装饰器信息),可进一步组合 inspect.signature()、inspect.getsource()、inspect.getfile() 等。
掌握这套 inspect 组合技,你就能构建健壮的元编程逻辑、自动化 API 文档工具,或实现灵活的插件注册机制。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











