为何Python脚本无法导入模块,而REPL环境中却可以?
脚本与REPL模块导入差异的底层原因
现象
执行脚本python3 x.py时提示找不到my_favorite_module模块,脚本代码如下:
import os os.chdir("/app/my-favorite-module") from my_favorite_module.foo import Bar os.chdir("/app")
但在脚本同一目录启动Python REPL,执行完全相同的代码却能成功导入:
root@afad0fa67aa8:/content# python3 Python 3.10.6 (main, May 29 2023, 11:10:38) [GCC 11.3.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import os; os.chdir("/app/my-favorite-module") >>> from my_favorite_module.foo import Bar >>> os.chdir("/app")
底层原因
Python的模块导入逻辑完全依赖sys.path这个路径列表,而这个列表的初始化规则在脚本运行模式和交互REPL模式下有本质区别:
- 脚本运行模式:当你用
python3 x.py执行脚本时,Python会把脚本文件所在的目录作为sys.path的第一个元素。此时sys.path中并不包含你通过os.chdir切换到的/app/my-favorite-module,而且os.chdir只会改变当前工作目录,不会自动更新sys.path,所以Python找不到目标模块。 - 交互REPL模式:启动REPL时,Python会把空字符串
''放在sys.path的最前端,这个空字符串代表当前工作目录。当你用os.chdir切换到/app/my-favorite-module后,''对应的实际路径就变成了该目录,Python导入模块时会优先在这个路径下查找,因此能成功找到my_favorite_module。
简单来说,脚本模式下sys.path的首位是脚本所在目录,REPL模式下sys.path的首位是当前工作目录,这就是导致两种场景导入结果不同的核心原因。
内容的提问来源于stack exchange,提问作者Foobar
相关产品推荐
相关产品推荐

