Python解释器执行import语句时第一个搜索的目录是当前脚本所在目录。该目录对应sys.path[0],其具体值取决于启动方式:python script.py时为脚本绝对路径,python -m时为当前工作目录(空字符串'')。

Python 的 import 机制默认会优先搜索当前目录,但这个“当前目录”不是你直觉以为的那个目录——它取决于你如何启动 Python 解释器。
python script.py 启动时,sys.path[0] 是脚本所在目录
当你执行 python main.py,Python 会把 main.py 所在的绝对路径插入到 sys.path[0]。这意味着:如果 utils.py 和 main.py 在同一目录,import utils 就能直接成功。
但要注意:
- 这个“当前目录”是
main.py文件的位置,不是你终端当前工作目录(pwd输出的路径) - 如果你在子目录里运行
python ../main.py,sys.path[0]是../的绝对路径,不是你所在的子目录 - 一旦模块被成功导入,它会被缓存进
sys.modules,后续再import同名模块不会重新搜索路径
python -m package.module 启动时,sys.path[0] 是空字符串
这种启动方式下,sys.path[0] 是 '',它代表「当前工作目录」(即你执行命令时所在的目录),而不是脚本位置。这时 import 是否成功,取决于你是否在正确的包根目录下运行命令。
立即学习“Python免费学习笔记(深入)”;
常见错误现象:
- 项目结构为
myproject/ ├── __init__.py ├── main.py └── utils.py,你在myproject/下执行python -m main,没问题 - 但如果你 cd 进
myproject/的子目录再执行,就会报ModuleNotFoundError: No module named 'utils' - 即使
utils.py就在同级,python -m也不会自动把main.py所在目录加进sys.path
当前目录模块覆盖标准库是真实风险
如果你在项目里新建了一个 json.py 或 os.py,然后执行 import json,Python 会优先加载你本地的 json.py,而不是标准库的 json 模块——这会导致 AttributeError 或完全不可预期的行为。
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
验证方法很简单:
import json print(json.__file__)
如果输出路径指向你项目里的 json.py,就踩中了这个坑。
规避建议:
- 避免用标准库模块名命名自己的文件(
random.py、sys.py、http.py等全都要避开) - CI 流程中可加一步检查:
python -c "import sys; print([m for m in sys.builtin_module_names if m in [f.split('.')[0] for f in os.listdir('.')]])" - 开发时用
pip install --upgrade pip setuptools并启用pip check,部分冲突会在安装阶段暴露
手动调整 sys.path 有副作用,慎用 insert(0, ...)
虽然 sys.path.insert(0, current_dir) 能强行让当前目录优先,但它破坏了 import 的可预测性,尤其在多人协作或部署环境中:
- 其他开发者或 CI 环境运行时,可能因为路径拼接逻辑不同导致行为不一致
- 如果多个模块都做类似操作,
sys.path会变得冗长且难以调试 - 打包成
pyz或用 PyInstaller 时,sys.path动态修改可能失效或引发重复导入
更稳妥的做法是统一使用 -m 启动 + 正确的包结构,或通过 PYTHONPATH 环境变量声明依赖路径,而不是在代码里硬编码路径操作。
真正容易被忽略的是:同一个 import xxx 语句,在不同启动方式下,背后走的是两套完全不同的路径解析逻辑——不明确启动上下文,就无法稳定复现或修复 import 错误。

















