Sherioc's Blog
文章
python基础

Python 导入与 sys.path 复盘

2026年4月4日 2 分钟阅读 浏览 0 喜欢 0 评论 0

image.png

一、Python 导入的核心规则

  1. Python 找模块只看一个地方:sys.path

    • sys.path 是一个路径列表
    • 执行 import 时,Python 按顺序在这些目录里查找包/模块
    • 第三方库(PyQt6、numpy 等)都在 site-packages,它默认就在 sys.path 里
  2. 绝对导入 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__)))
  1. __file__:当前 .py 文件的完整路径
  2. os.path.dirname(...):获取所在文件夹
  3. 套两层 → 拿到项目上级目录
  4. sys.path.insert(0, 路径):把该目录加到 Python 搜索路径最前面
  5. 目的:让 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
  • 入口文件:不用 .,只用绝对导入
  • 手动把根目录加入搜索路径,保证在哪运行都不报错

五、简要

  1. 直接运行 → 不能用 .
  2. 包内引用 → 可以用 .
  3. import 只看 sys.path
  4. 找不到模块就把目录加进 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
评论区在赶来的路上...