Python: 使用pickle模块保存和加载对象时的错误

0 投票
2 回答
2357 浏览
提问于 2025-04-16 09:16

我正在尝试用这段代码来加载和保存对象,这段代码是我一周前问的一个问题中得到的:Python: 保存和加载对象以及使用pickle。

这段代码是这样的:

class Fruits: pass

banana = Fruits()    
banana.color = 'yellow'     
banana.value = 30

import pickle

filehandler = open("Fruits.obj","wb")    
pickle.dump(banana,filehandler)    
filehandler.close()

file = open("Fruits.obj",'rb')    
object_file = pickle.load(file)    
file.close()

print(object_file.color, object_file.value, sep=', ')

乍一看,这段代码运行得不错,可以加载并查看保存对象的'color'和'value'。但是,我想要的是关闭一个会话,打开一个新会话,然后加载我在过去的会话中保存的内容。我在添加了filehandler.close()这一行后关闭了会话,然后打开一个新会话,并把剩下的代码放进去。接着在执行object_file = pickle.load(file)时,我遇到了这个错误:

Traceback (most recent call last): 
File "<pyshell#5>", line 1, in <module> 
object_file = pickle.load(file) 
File "C:\Python31\lib\pickle.py", line 1365, in load 
encoding=encoding, errors=errors).load() 
AttributeError: 'module' object has no attribute 'Fruits' 

有没有人能告诉我这个错误信息是什么意思,并教我怎么解决这个问题?

非常感谢,祝大家新年快乐!!

2 个回答

0

所以……这是为什么很多做面向对象编程的人不太使用pickle的原因之一——它在序列化和反序列化(也就是把数据保存和读取)方面表现得很糟糕。特别是当你改变命名空间时,可能会找不到对象的定义!那么,有什么替代方案呢?

有两个替代方案,分别是dill和cloudpickle。我个人更喜欢dill,但这两者都能满足你的需求。你可以用pip安装其中一个,然后像这样使用:

import dill as pickle

或者

import cloudpickle as pickle

然后就可以安心享受你的午餐了。

4

Python 并不会把整个类都保存下来,而只是保存类的名字。因此,当你要把这些类从文件中恢复出来时,必须确保包含这些类的模块已经保存到文件中,并且可以被导入。Python 会在恢复时重新导入这些类。

如果你遇到问题,可能需要定义一些特殊的辅助方法,叫做 __getstate____setstate__,它们是用来处理保存和恢复的。

撰写回答