问题在于,您 实际上是通过运行“设置”模块 来 腌制“设置”中定义的对象的 ,然后才尝试从
GUI模块中释放对象。
请记住,泡菜实际上并没有存储有关如何构造类/对象的信息,并且在进行酸洗时需要访问该类。有关更多详细信息,请参见有关使用Pickle的Wiki。
在pkl数据中,您看到所引用的对象是
__main__.Manager,因为在创建pickle文件时,“设置”模块是 主要的
(即,您将“设置”模块作为调用该
addUser功能的主要脚本运行)。
然后,您尝试取消对’Gui’的选择-
使该模块具有名称
__main__,然后在该模块中导入Setting。因此,当然Manager类实际上是
Settings.Manager。但是pkl文件不知道这一点,而是在中查找Manager类
__main__,并抛出AttributeError,因为它不存在(
Settings.Manager确实存在,但
__main__.Manager不存在)。
这是演示的最小代码集。
该
class_def.py模块:
import pickleclass Foo(object): def __init__(self, name): self.name = namedef main(): foo = Foo('a') with open('test_data.pkl', 'wb') as f: pickle.dump([foo], f, -1)if __name__=='__main__': main()您运行上述操作以生成泡菜数据。该
main_module.py模块:
import pickleimport class_defif __name__=='__main__': with open('test_data.pkl', 'rb') as f: users = pickle.load(f)您运行上面的内容尝试打开pickle文件,这将引发与您看到的大致相同的错误。(略有不同,但是我猜那是因为我使用的是Python 2.7)
解决方案是:
- 您可以通过显式导入使该类在顶级模块(即GUI或main_module)的命名空间中可用,或者
- 您可以从与打开该文件相同的顶层模块中创建该pickle文件(即,
Settings.addUser
从GUI或class_def.main
main_module进行调用)。这意味着pkl文件会将对象另存为Settings.Manager
或class_def.Foo
,然后可以在GUI``main_module
命名空间中找到它们。
选项1的示例:
import pickleimport class_deffrom class_def import Foo # import Foo into main_module's namespace explicitlyif __name__=='__main__': with open('test_data.pkl', 'rb') as f: users = pickle.load(f)选项2的示例:
import pickleimport class_defif __name__=='__main__': class_def.main() # Objects are being pickled with main_module as the top-level with open('test_data.pkl', 'rb') as f: users = pickle.load(f)


