inspect.getmembers() 返回大量内置和继承成员,需用 predicate 过滤;区分方法类型需结合描述符协议与 isstaticmethod/isclassmethod;signature 报错时应捕获异常并设为 empty;继承分析优先用 getmro 而非 mro__;动态类需回退 __dict 解析。

inspect.getmembers() 为什么返回一堆奇怪的属性?
直接用 inspect.getmembers(MyClass) 会混入大量内置方法(如 __dict__、__module__)和继承链上的父类成员,根本看不出你定义了哪些东西。关键不是“获取所有成员”,而是“过滤出你真正关心的”。
实操建议:
- 用
predicate参数限定类型,比如只看函数:inspect.getmembers(MyClass, predicate=inspect.isfunction) - 想看实例方法(含
self参数的),用inspect.ismethod;但注意:在类对象上它只返回绑定到类的方法(如类方法、静态方法),不包括普通实例方法——后者得用inspect.isfunction配合not inspect.isbuiltin排除掉 C 实现的函数 - 过滤掉私有成员(双下划线开头但不结尾):
lambda m: not m[0].startswith('_')
如何区分 @staticmethod、@classmethod 和普通实例方法?
仅靠 inspect.isfunction 或 inspect.ismethod 无法准确分类,因为装饰器改变了对象类型。必须结合 inspect.signature() 和描述符协议来判断。
实操建议:
- 先用
inspect.getmembers(MyClass, inspect.isfunction)拿到所有函数对象 - 对每个函数,检查其是否是类的属性描述符:
hasattr(getattr(MyClass, name), '__get__')—— 如果是,再看它是否被@classmethod或@staticmethod包装 - 更可靠的方式是查
getattr(MyClass, name).__func__是否存在(@classmethod有),或直接调用inspect.isstaticmethod()/inspect.isclassmethod()(Python 3.12+ 才有,旧版本需手动判断) - 普通实例方法的 signature 第一个参数名通常是
'self',但不能只依赖这点——有些函数参数叫'self'却不是方法
inspect.signature() 报错 "ValueError: no signature found" 怎么办?
常见于 C 扩展函数(如 len、list.append)、内置方法(str.upper)、或使用了 @functools.wraps 但没正确传递 __signature__ 的装饰器函数。
实操建议:
- 加 try/except 包裹:
try: sig = inspect.signature(obj) except (ValueError, TypeError): sig = inspect.Signature.empty - 对类方法,别直接传
MyClass.method,而应传MyClass.__dict__['method'](绕过绑定逻辑,拿到原始函数) - 若用自定义装饰器,确保它设置了
__signature__:wrapped.__signature__ = inspect.signature(func)
想看类的继承关系和 MRO,别只用 __mro__
MyClass.__mro__ 是元组,可读性差,且不显示哪些是显式继承、哪些是通过 __bases__ 动态注入的。inspect 提供了更结构化的接口。
实操建议:
- 用
inspect.getmro(MyClass)—— 和__mro__等价,但语义更明确 - 要分析继承来源,组合使用:
inspect.getfile(MyClass)查定义位置,inspect.getsourcefile(MyClass)判断是否来自源码(排除 built-in 类) - 检查是否为抽象基类:
inspect.isabstract(MyClass),避免误把 ABC 当普通类处理 - 注意:
inspect.getclasstree()只适合小范围类集合,对大型项目继承图容易爆炸,慎用
最常被忽略的是:inspect 对动态生成的类(比如用 type() 构造、或 metaclass 修改过的)支持有限——__doc__、__annotations__、甚至 __signature__ 可能为空或错乱,这种时候得回退到直接读取 __dict__ 并人工解析。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











