
本文详解如何利用 Python 的 inspect 模块系统性地提取模块中类、实例及函数的所有属性、方法、静态变量等成员信息,涵盖过滤策略、实用示例与关键注意事项。
本文详解如何利用 python 的 `inspect` 模块系统性地提取模块中类、实例及函数的所有属性、方法、静态变量等成员信息,涵盖过滤策略、实用示例与关键注意事项。
在 Python 开发与调试过程中,动态探查对象结构是常见需求——例如分析第三方库接口、生成文档、实现插件反射机制或进行单元测试前的元信息收集。inspect 模块作为标准库中专为“内省(introspection)”设计的核心工具,提供了强大而精细的 API 来获取函数、类、模块等对象的运行时元数据。
要获取类的全部属性(包括类变量、实例变量、方法、特殊方法等),关键在于区分“类本身”与“类实例”的行为差异:
- 直接对类(如 mf.Attack)调用 inspect.getmembers() 会返回其定义时的静态成员(含未绑定方法、类属性);
- 对实例(如 mf.Attack())调用则会包含实例字典(__dict__)、继承链中的方法以及已初始化的实例属性(本例中无显式 __init__,故 __dict__ 为空)。
以下是一个完整、可复用的实践方案:
import my_file as mf
import inspect
# ✅ 获取模块中所有类名
def get_all_classes(module) -> list:
return [name for name, obj in inspect.getmembers(module, inspect.isclass)]
# ✅ 获取某类的所有公共/非私有属性(排除双下划线特殊方法,保留类变量和普通方法)
def get_class_attributes(cls, include_private=False, exclude_dunder=True):
members = inspect.getmembers(cls)
filtered = []
for name, value in members:
# 过滤条件:是否为私有(以单下划线开头)、是否为双下划线方法
if not include_private and name.startswith('_') and (exclude_dunder and name.startswith('__') and name.endswith('__')):
continue
if not include_private and name.startswith('_') and not (name.startswith('__') and name.endswith('__')):
continue # 可选:跳过单下划线私有成员
filtered.append((name, value))
return filtered
# ✅ 获取类的静态属性(不依赖实例)——推荐方式
attack_class_attrs = get_class_attributes(mf.Attack)
print("Class-level attributes (static):")
for name, val in attack_class_attrs:
if not inspect.isfunction(val) and not inspect.ismethod(val):
print(f" {name} = {repr(val)}") # 如 ss = 741
# ✅ 获取类的方法(包括未绑定函数)
methods = [(n, v) for n, v in inspect.getmembers(mf.Attack, inspect.isfunction)]
print("\nDeclared methods:")
for name, func in methods:
print(f" {name}: {func}")
# ⚠️ 注意:the_function 是未绑定的普通函数(缺少 self 参数),非实例方法
# 若需正确绑定方法,请在类中定义为 def the_function(self): ...
重要提示与最佳实践:
- inspect.getmembers(obj, predicate) 的 predicate 参数是核心过滤器,常用值包括 inspect.isfunction、inspect.ismethod、inspect.isbuiltin、lambda x: not inspect.isroutine(x)(即非可调用对象,常用于提取属性);
- 类变量(如 ss = 741)属于类对象的直接属性,可通过 inspect.getmembers(Attack) 或 Attack.__dict__ 获取;
- 实例属性仅在实例创建并赋值后才存在(本例中 random_var = 56 在函数内定义,不属于类或实例属性,而是局部变量,无法通过 inspect 提取);
- 避免依赖 dir() + getattr() 组合做粗粒度过滤,因其无法区分继承自父类的成员与本类定义的成员,而 inspect.getmembers() 支持更精准的谓词控制;
- 生产环境中建议结合 inspect.signature() 分析函数参数,用 inspect.getdoc() 提取 docstring,构建完整接口文档。
通过合理组合 inspect 模块的各类函数,开发者可构建高度自动化的代码分析管道,显著提升开发效率与代码可维护性。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











