Python如何导入不同文件夹的文件?附项目报错解决请求
咱们先捋清楚你遇到的问题到底出在哪:当你运行profile/profile.py时,它把项目根目录(也就是../指向的SnapQuick文件夹)加到了sys.path里,然后导入了main.login。但login.py里写的import signup会去sys.path里找signup.py——可signup.py明明在main文件夹里,根目录下根本没有这个文件,这不就直接报ModuleNotFoundError了嘛!
下面给你几个实用的解决方案,按推荐程度排序:
方案1:统一用绝对路径导入(最省心)
既然已经把项目根目录加到了sys.path,那所有导入都从根目录的模块出发写绝对路径就行:
# 把login.py里的导入改成这样 import sqlite3 from os import sys, system sys.path.insert(1, "../") from main import signup # 明确从main模块导入signup from profile import profile from main import snap_main # 如果snap_main也在main文件夹,同样改过来 class login: def login(self): # 你的业务代码
profile.py里的导入可以保持原样,不过也建议统一成绝对路径写法,保持代码风格一致:
# profile.py from os import sys sys.path.insert(1, '../') from main import login import sqlite3 class profile(): def show_profile(self,user_id): # 你的业务代码
方案2:用相对导入(适合作为包管理的项目)
如果想把整个SnapQuick当成一个标准Python包来管理,那可以用相对导入。第一步先给每个文件夹加个空的__init__.py文件,让Python识别它们为包,结构变成:
SnapQuick ├─ main │ ├─ __init__.py │ ├─ snap_view.py │ ├─ login.py │ └─ signup.py └─ profile ├─ __init__.py └─ profile.py
然后修改导入语句:
- 在
login.py里,导入同文件夹的signup用相对路径:from . import signup # "."代表当前所在的main文件夹 from ..profile import profile # ".."代表父级的SnapQuick文件夹 from . import snap_main - 在
profile.py里导入login:from ..main import login
⚠️ 注意:这种方式不能直接在profile文件夹里运行python profile.py,得从SnapQuick的上级目录用模块方式运行,比如:
python -m SnapQuick.profile.profile
方案3:动态定位项目根目录(最稳定)
有时候用../这种相对路径容易出错,比如换个运行位置就失效了。可以用pathlib模块动态获取项目根目录,不管在哪运行都能正确找到:
比如在profile.py里:
from os import sys from pathlib import Path # 自动获取项目根目录(SnapQuick文件夹的绝对路径) ROOT_DIR = Path(__file__).parent.parent sys.path.insert(0, str(ROOT_DIR)) from main import login import sqlite3
在login.py里同样处理:
from os import sys, system from pathlib import Path ROOT_DIR = Path(__file__).parent.parent sys.path.insert(0, str(ROOT_DIR)) from main import signup from profile import profile from main import snap_main
这种方式的好处是彻底摆脱相对路径的限制,不管你从哪个目录运行脚本,都能正确加载模块。
最后提个小建议:正式项目里尽量少用sys.path.insert,如果可以的话,把项目根目录加到Python的环境变量PYTHONPATH里,这样就不用在每个脚本里手动加路径啦。
内容的提问来源于stack exchange,提问作者wilfredarin

