如何修复KivyMD项目AttributeError: 'super' object has no attribute '__getattr__'报错
问题根因排查及解决方案
这个错误是Kivy/KivyMD开发中的典型异常,本质是你尝试访问的Widget属性不存在,且当前Widget的ids字典中也没有对应的id,触发了父类super的__getattr__兜底逻辑抛出错误。结合你上传图片功能单独测试正常、整合到项目后报错的场景,按以下优先级排查:
常见触发原因
- kv布局id拼写错误,或访问id的层级不匹配:整合代码时容易把新功能的kv块放错嵌套层级,比如上传图片的组件定义在子Screen中,你直接在App类或父级ScreenManager中访问子Screen的id,就会触发该错误。
- 访问
ids的时机错误:Kivy的ids字典要等Widget的__init__执行完成、kv布局完全加载后才会生成,如果你在自定义组件的__init__方法中直接访问ids,就会触发错误。单独测试时布局层级简单、加载速度快可能不会暴露问题,整合后布局层级变多、加载时序变化就会触发异常。 - 动态生成的上传组件未绑定到
ids:如果上传图片相关组件是用Python代码动态生成的,没有手动绑定到当前Widget的ids字典,直接访问也会报错。 - Screen加载时序问题:如果上传功能放在独立Screen中,你在还未切换到该Screen、Screen未完成加载时就访问它的
ids,也会触发错误。单独测试时默认打开上传功能所在Screen,加载完成后才执行逻辑所以不会出问题。
对应解决方案
- 校验id正确性与访问层级:确认你调用
self.ids.xxx的self对象,就是你定义id所在的kv组件的绑定类。跨层级访问需要先拿到对应Widget的实例,比如要访问ScreenManager内子Screen的id,需要用self.root.get_screen('对应Screen的name属性').ids.xxx的方式访问,禁止直接跨层级取id。 - 调整
ids访问时机:不要在自定义组件的__init__方法中访问ids,把相关逻辑移到on_kv_post方法中,或者用Clock.schedule_once延迟1帧执行,示例代码:
from kivy.clock import Clock class UploadScreen(Screen): def __init__(self, **kwargs): super().__init__(**kwargs) # 不要在这里写访问ids的逻辑 Clock.schedule_once(self.init_upload_func, 0) def init_upload_func(self, dt): # 此处访问ids不会报错 print(self.ids.upload_btn)
- 动态组件手动绑定
ids:如果上传相关组件是Python代码动态生成的,手动把实例添加到ids字典:
upload_input = MDFileSelector() self.add_widget(upload_input) self.ids['upload_input'] = upload_input
- 适配Screen加载时序:如果需要提前操作其他Screen内的组件,可把对应Screen的
pre_virtual属性设为True开启预加载,或者把上传相关逻辑移到Screen的on_enter方法中,等Screen加载完成后再执行。
快速验证方法
在报错的代码行前加入两行打印代码:
print(self.ids.keys()) print(hasattr(self, '你要访问的属性名'))
可快速确认是id拼写问题、层级问题还是时序问题。
内容的提问来源于stack exchange,提问作者Edwin
相关产品推荐
相关产品推荐

