为何Python中文件内全局对象与导入时会生成不同实例?
问题解答
这确实是Python模块导入机制里需要留意的陷阱,本质和lru_cache无关,根源是同一个文件被加载了两次,生成了两个独立的模块实例。
原因解析
当你直接运行file_1.py时,Python会将这个文件作为__main__模块加载;而file_2.py中执行from file_1 import add时,Python会以file_1的模块名重新加载该文件。这就导致内存中存在两个完全独立的file_1模块实例:
- 一个是作为入口脚本的
__main__模块,里面的add函数带着你在if __name__ == "__main__"块中调用产生的缓存; - 另一个是被
file_2导入的file_1模块,里面的add函数是全新的实例,缓存也是独立的。
解决方法
- 拆分代码结构:将需要被其他模块复用的代码(比如
add函数)放到单独的模块(例如utils.py)中,入口脚本file_1.py仅负责调用逻辑,不存放可复用的函数定义。这样所有模块导入的都是同一个utils模块实例,缓存自然共享。 - 临时应急方案(不推荐):如果必须在入口脚本中定义可复用函数,可以在
file_1.py开头添加如下代码,强制将__main__模块映射为file_1模块:
这种方法容易引发其他导入问题,仅适合临时场景。import sys if __name__ == "__main__": sys.modules["file_1"] = sys.modules["__main__"]
相关文档说明
这个现象属于Python模块导入的基础行为,在Python官方文档的模块章节中有明确说明:脚本文件被直接运行时,其模块名为__main__;而被其他模块导入时,模块名为文件名。这种模块名差异会触发重复加载,生成独立的模块实例。lru_cache的文档不会提及此问题,因为这并非缓存装饰器自身的特性,而是模块加载机制导致的衍生问题。
内容的提问来源于stack exchange,提问作者pythonweb
相关产品推荐
相关产品推荐

