调用inspect.getmro()报错:Object has no attribute '__bases__' 问题排查
首先我得指出一个关键的小失误——你调用inspect.getmro()的时候传的是类的实例,而不是类本身!inspect.getmro()的参数要求是类对象,不是实例对象。正确的调用姿势应该是:
import inspect import myfilename inspect.getmro(myfilename.MyClassName) # 传类,不是实例化后的对象
如果纠正这个之后还是遇到Object has no attribute '__bases__'的错误,那大概率和Apache Storm MultiLang里Storm.Bolt的实现有关,下面具体分析和解决:
可能的原因
Apache Storm的Python组件里的Storm.Bolt基本是Python 2.x的旧式类(也就是没有显式继承object的类),或者是通过动态机制生成的类。在Python 2.x中,旧式类的内部结构和新式类有差异,__bases__属性的存在逻辑或者inspect模块的处理方式不同,才会导致报错。
解决方案
1. 转为新式类继承
修改你的类定义,让它同时继承object,把旧式类转为新式类:
from storm import Storm class MyClassName(Storm.Bolt, object): # 你的类实现代码
新式类在Python 2.x中会正确维护__bases__属性,inspect.getmro()也能正常解析它的方法继承顺序。这种方式完全不会影响Storm Bolt的核心功能,因为Storm的Bolt逻辑是基于方法约定(比如process方法),和类的继承类型无关。
2. 手动遍历继承关系(不想修改类定义时用)
如果不能调整类的继承结构,可以手动遍历类的__base__属性来构建方法解析顺序:
def get_mro(cls): mro = [] current = cls while current is not None: mro.append(current) current = getattr(current, '__base__', None) return mro # 调用示例 mro = get_mro(myfilename.MyClassName) for cls in mro: print(cls.__name__)
3. 排查Storm.Bolt的实际结构
如果以上方法都不生效,可以先确认Storm.Bolt的类结构,看看它是不是动态生成的:
from storm import Storm print(dir(Storm.Bolt)) print(Storm.Bolt.__class__) print(Storm.Bolt.__bases__ if hasattr(Storm.Bolt, '__bases__') else "No __bases__ attribute")
如果它是通过工厂函数或者元类动态生成的,可能需要调整获取MRO的方式,比如先通过type()获取实例的类后再处理。
内容的提问来源于stack exchange,提问作者Crackerman

