一、Python 导入的核心规则
Python 找模块只看一个地方:
sys.pathsys.path是一个路径列表- 执行
import时,Python 按顺序在这些目录里查找包/模块 - 第三方库(PyQt6、numpy 等)都在
site-packages,它默认就在sys.path里
绝对导入 vs 相对导入
- 绝对导入:
from a.b import c从sys.path里的某个目录开始找,最稳定、最推荐 - 相对导入:
from .a import c仅用于包内部文件之间互相导入,不能用于直接运行的脚本
- 绝对导入:
二、相对导入 . 的使用限制
.代表“当前包目录”直接运行的文件(python main.py )不能用相对导入 原因:运行时该文件被视为顶层脚本
__main__,不属于任何包,Python 不知道.指向谁 报错:attempted relative import with no known parent package适用场景:包内部模块互相引用
python# controller/main_controller.py from .utils import helper # 正确
三、sys.path.insert(0, ...) 到底做什么
python
sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
__file__:当前.py文件的完整路径os.path.dirname(...):获取所在文件夹- 套两层 → 拿到项目上级目录
sys.path.insert(0, 路径):把该目录加到 Python 搜索路径最前面- 目的:让
from pointcloud_gui.controller...这种包式导入可以找到
四、直接运行脚本的标准写法
python
import sys
import os
sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
from pointcloud_gui.controller.main_controller import MainController
- 入口文件:不用
.,只用绝对导入 - 手动把根目录加入搜索路径,保证在哪运行都不报错
五、简要
- 直接运行 → 不能用
. - 包内引用 → 可以用
. - import 只看 sys.path
- 找不到模块就把目录加进 sys.path
python
"""Entry point for the point cloud GUI application."""
import sys
import os
# =====================调试=====================
print("当前文件 __file__ =", __file__) # E:\Desktop\Project\Project_CAGE\CAGE_ReBuild\GUI\pointcloud_gui\main.py
# 第一层 dirname:当前文件所在文件夹(pointcloud_gui)
dir1 = os.path.dirname(__file__)
print("第一层 os.path.dirname(__file__) =", dir1) # E:\Desktop\Project\Project_CAGE\CAGE_ReBuild\GUI\pointcloud_gui
# 第二层 dirname:上级文件夹(GUI 文件夹)
dir2 = os.path.dirname(dir1)
print("第二层 os.path.dirname(...) =", dir2) # E:\Desktop\Project\Project_CAGE\CAGE_ReBuild\GUI
# print(sys.path)
# ['E:\\Desktop\\Project\\Project_CAGE\\CAGE_ReBuild\\GUI\\pointcloud_gui', 'C:\\Users\\Administrator\\.conda\\envs\\build3d\\python310.zip', 'C:\\Users\\Administrator\\.conda\\envs\\build3d\\DLLs', 'C:\\Users\\Administrator\\.conda\\envs\\build3d\\lib', 'C:\\Users\\Administrator\\.conda\\envs\\build3d', 'C:\\Users\\Administrator\\.conda\\envs\\build3d\\lib\\site-packages', 'C:\\Users\\Administrator\\.conda\\envs\\build3d\\lib\\site-packages\\win32', 'C:\\Users\\Administrator\\.conda\\envs\\build3d\\lib\\site-packages\\win32\\lib', 'C:\\Users\\Administrator\\.conda\\envs\\build3d\\lib\\site-packages\\Pythonwin']
# =========================================================
sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
from PyQt6.QtWidgets import QApplication
from pointcloud_gui.controller.main_controller import MainController
def main():
app = QApplication(sys.argv)
app.setStyle("Fusion")
controller = MainController()
controller.show()
sys.exit(app.exec())
if __name__ == "__main__":
main()
喜欢 0
评论区在赶来的路上...