pickle load自定义对象报错

Python中的pickle可以保存Python中的任意对象到文件中。当我们dump一个自定义类实例化出来的对象之后,如果需要在其他Python模块(文件)中load进来,需要注意,一定要先导入这个自定义的类,否则执行对象的方法的时候会报错

实例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import pickle

class A:
def __init__(self, name):
self.name = name

def show(self):
print(self.name)
return self.name

if __name__ == "__main__":
print("--dump--")
a = A("polarsnow")
pickle.dump(a, open('db', 'wb'))

print("--load--")
ret = pickle.load(open('db', 'rb'))
print(ret)
ret.show()

------------
--dump--
--load--
<__main__.A object at 0x101b77e10>
polarsnow
  • 创建一个自定义的类
  • 实例化这个类的对象
  • 将这个对象从内存中dump到一个文件中
  • 从本程序load pickle文件到内存中
  • 执行对象的一个方法

上面从本程序中,load自定义类实例化出来的对象,执行对象的操作是没有问题的。那么如果是从另一个文件load这个对象呢?

1
2
3
4
5
6
7
8
9
import pickle

ret = pickle.load(open('db', 'rb'))

------------
Traceback (most recent call last):
File "/Users/lvrui/PycharmProjects/untitled/8/loadpickle.py", line 3, in <module>
ret = pickle.load(open('db', 'rb'))
AttributeError: Can't get attribute 'A' on <module '__main__' from '/Users/lvrui/PycharmProjects/untitled/8/loadpickle.py'>

从另一个Python文件中load一个自定义类的对象时报错了!为什么会报错?因为对象是由类而产生的,在新的Python文件中,类没有被加载到内存中,所以load这个类的对象的时候就会报错。在报错信息中也可以看出,没有在当前文件中找到A这个类。

解决这个问题有两个途径:

  • 将类导入到这个Python文件中
  • 将类的代码直接copy到这个文件中
1
2
3
4
5
6
7
8
9
10
import pickle
from dumppickle import A

ret = pickle.load(open('db', 'rb'))
print(ret)
ret.show()

------------
<dumppickle.A object at 0x1013777b8>
polarsnow

注意:一个对象,有它对应的类才有意义。所以在load pickle文件中的对象的时候,一定要保证它的类先被导入