跳到主要内容

模块与包

合理组织模块与包,是项目可维护性的基础。本篇梳理导入机制与常见实践。

import 机制

Python 在 sys.path 列出的目录中按名查找模块。import 同一模块只执行一次,结果缓存在 sys.modules

import os
from pathlib import Path
from collections import Counter, defaultdict

__name__ == "__main__"

模块被直接运行(python mod.py)时,__name__"__main__";被导入时则为模块名。常用作脚本入口守卫。

def main():
...

if __name__ == "__main__":
main()

__init__.py

包目录下含 __init__.py 即为“常规包”。该文件可空着,也可用于暴露公共 API,例如 from .core import Engine

3.3+ 还支持“无 __init__.py”的命名空间包(PEP 420),允许多个目录共同构成一个包,适合拆分大型项目。

包与子包

目录嵌套即构成子包,导入路径用点号分隔:

mypkg/
__init__.py
sub/
__init__.py
mod.py

对应导入 from mypkg.sub import mod

绝对导入 vs 相对导入

  • 绝对导入:从项目根开始的完整路径,如 from mypkg.utils import x,推荐方式,可读性高
  • 相对导入:用 . 表示当前包,.. 表示上级包,如 from .utils import x,适合包内部强耦合场景

绝对导入是默认推荐,可避免包结构变动后导入路径失效。

命名空间包

__init__.py 的目录也是合法的包,可被拆分布署,适合插件式架构或微内核场景。代价是没有 __init__.py 提供的集中初始化位置。