Python中import __main__的作用及pickle场景报错解决疑问
Python中
import __main__的作用及Pickle序列化相关问题解析 一、import __main__的通用作用
- __main__是Python的特殊内置模块,它指向当前程序的入口执行脚本。当你直接运行一个
.py文件时,这个文件的__name__属性会被自动设置为'__main__',此时该文件就成为了__main__模块。 - 使用
import __main__的核心目的是跨模块访问入口脚本的全局命名空间。比如你在入口脚本里定义了全局变量、函数或类,其他模块只要导入__main__,就能直接调用这些对象——相当于拿到了入口脚本的全局上下文。 - 举个简单例子:假设你有个入口脚本
run.py,里面写了def greet(): print("Hi there!");在同目录的utils.py里执行import __main__后,就能通过__main__.greet()调用这个函数。
二、为什么import __main__能解决Pickle反序列化的AttributeError
先明确报错的根本原因:
当你在脚本的if __name__ == "__main__":代码块里用Pickle序列化对象时,Pickle会把对象的类归属记录为__main__.theObject(因为此时执行的脚本是__main__模块)。但当你换另一个脚本反序列化时,当前的__main__模块变成了新的脚本,而这个新脚本里并没有定义theObject类,自然就会抛出找不到属性的错误。
而import __main__能解决这个问题的关键:
- 当你在反序列化的脚本里执行
import __main__,这里导入的__main__其实是你当初序列化对象时的那个入口脚本模块(前提是原脚本在Python的搜索路径范围内)。此时Pickle要找的__main__.theObject就指向了原脚本里定义的类,而非当前新脚本的__main__模块,自然就能成功找到类定义完成反序列化。
补充:更规范的替代方案
其实这种依赖__main__的做法不算最佳实践,更稳妥的方式是把需要序列化的类单独放到一个公共模块里。比如创建my_models.py,把theObject类定义在里面;序列化和反序列化的脚本都通过from my_models import theObject来引用这个类。这样Pickle会记录类的归属为my_models.theObject,两边的模块一致,就不会出现找不到属性的问题,也不需要依赖__main__。
内容的提问来源于stack exchange,提问作者KansaiRobot
相关产品推荐
相关产品推荐

