Python Project Configurations

Python Project Configurations

Python是如何查找模块的?有哪些查找路径?

Python 在导入模块时,会按照 sys.path 中的路径顺序查找模块。sys.path 默认包含:

  1. 当前脚本所在目录examples/.,取决于执行方式)
  2. PYTHONPATH 环境变量指定的目录
  3. Python 标准库目录
  4. site-packages(第三方库安装目录)

为什么 Python 不自动把执行目录(./)加入 sys.path

  1. 避免隐式依赖
    • 如果 Python 自动把执行目录加入 sys.path,可能会导致 不同环境下模块导入行为不一致(比如在 A/B/ 目录下运行同一个脚本,导入的模块可能不同)。
    • 这会让代码的 可移植性变差
  2. 防止命名冲突
    • 如果 ./ 被自动加入 sys.path,可能会意外导入错误的模块(比如当前目录有一个 random.py,会覆盖 Python 标准库的 random)。
  3. 明确性优先
    • Python 倾向于 显式优于隐式(Explicit is better than implicit),所以模块查找路径需要开发者明确指定。

Python包导入机制

导入方式

  1. 绝对导入:sys.path.append(os.path(...))
  2. 相对导入

运行包里的Python文件

这是 Python 包导入机制的经典问题。两种方式的区别如下:


1. PYTHONPATH=. python marl_framework/main.py

  • 这种方式把当前目录(项目根目录)加入了模块查找路径。

2. python -m marl_framework.main

  • 这种方式要求你在项目根目录下运行,并且 marl_framework 必须是一个包(有 __init__.py)。
  • Python 会把项目根目录当作包的根目录,marl_framework 作为包被导入。
  • 这时,所有导入都要用包内绝对导入(如 from marl_framework import constants),不能用裸导入(import constants),否则会找不到模块。
  • 优点:更规范,支持包内相对导入,适合大型项目和分发。

总结

  • PYTHONPATH=. 方式适合小脚本临时跑,但不适合包结构的项目。
  • python -m marl_framework.main 是推荐方式,适合包结构项目,导入更规范,兼容性更好。

建议:
如果你的项目是包结构,推荐用 python -m marl_framework.main 并用包内绝对导入。这样以后项目更易维护和分发。