Streamlit部署ML模型报'dict' object is not callable错误咨询
'dict' object is not callable 报错根因说明 这个报错的核心原因是你用变量名覆盖了Python内置的list类型,具体逻辑如下:
- Python中
list本身是内置的可调用类型,作用是将传入的可迭代对象转换为列表,你代码第15行原本写的list(enumerate(sim)),就是想把enumerate返回的迭代器转成列表,属于常规合法写法。 - 但你在代码第9行写了
list=pickle.load(...),这行代码把pickle加载出来的字典对象,直接赋值给了名为list的全局变量。赋值完成后,当前脚本全局作用域里的list就不再是原本的内置列表类型,而是你加载的那个字典对象。 - 字典属于不可调用对象,不能像函数/类一样后面跟
()传参执行,所以代码运行到list(enumerate(sim))时,Python尝试调用那个字典对象,就会抛出'dict' object is not callable错误。
你提到代码在Colab可以正常运行,是Colab的单元格分步运行机制导致的作用域差异:如果你在Colab中定义
recomm函数时,还没有执行list=pickle.load(...)这行赋值,函数内部查找list标识时会拿到未被覆盖的内置list对象,就不会触发报错;而VSCode运行时是整份脚本从头顺序执行,赋值语句先执行把全局list替换为字典,后续函数内调用list()时就会拿到字典触发错误。
两种可行的修复方案:
- 规范写法:不要使用Python内置类型/关键字作为变量名。把第9行的变量名从
list改成其他名称,比如movies_dict,对应修改第10行代码为movies=pd.DataFrame.from_dict(movies_dict),这种改法下哪怕第15行保留list()转换逻辑,代码也能正常运行。 - 你自行测试的删去第15行
list的写法也可正常运行:因为sorted()方法本身就支持直接接收迭代器作为入参,不需要手动先把enumerate的结果转成列表,去掉冗余的list()转换后,自然不会触发调用被覆盖的list变量的问题。
内容的提问来源于stack exchange,提问作者Nikhar Doshi
相关产品推荐
相关产品推荐

