6. 模块
import 语义、__main__ 入口、sys.path、编译缓存、包/相对导入与 __all__——和 ESM/CommonJS 对齐又要记清差异。
6.1 模块是什么
- 一个
.py文件通常对应一个模块;模块有自己的命名空间。 - 模块名 = 文件名去掉
.py(包内则是pkg.sub.mod)。
# fibo.py
def fib(n: int) -> None:
a, b = 0, 1
while a < n:
print(a, end=" ")
a, b = b, a + b
print()
def fib2(n: int) -> list[int]:
result: list[int] = []
a, b = 0, 1
while a < n:
result.append(a)
a, b = b, a + b
return result6.2 导入方式(从最安全到最慎用)
import fibo
fibo.fib(1000)
from fibo import fib, fib2 as fibonacci
fibonacci(1000)
import fibo as fb
fb.fib(1000)from fibo import *:污染命名空间且导入列表不可见;除非包用__all__明确出口且你有理由。- 热重载(仅 REPL / 少数工具场景):
importlib.reload(fibo),注意旧引用可能仍指向旧对象。
6.3 脚本入口:__name__
被直接运行的文件:__name__ == "__main__"。被 import 时:__name__ == "fibo"。
if __name__ == "__main__":
import sys
fib(int(sys.argv[1]))python fibo.py 50这也让同一个文件既可当库又可当 CLI:对齐「export function + if require.main」的心智,只是语法不同。
6.4 搜索路径:sys.path
- 入口脚本目录或
-m相关路径 PYTHONPATH- 标准库与
site-packages
import sys
print(sys.path[:3]) # 调试「为什么 import 找不到」时的第一步临时插入路径(脚手架里偶尔用;库代码应通过打包解决):
sys.path.insert(0, "/your/extra/path")6.5 __pycache__ 与 .pyc
- 缓存加速导入;不加速运行热路径。
- 别手改
.pyc;时间戳不对会自动失效重编。
6.6 dir():自省
import fibo
print([name for name in dir(fibo) if not name.startswith("_")])6.7 包(package)
- 常规包:目录 +(多数团队仍放)
__init__.py。 - 命名空间包(3.3+):多个目录拼成同名包,适合大型单体拆分(进阶)。
sound/
__init__.py
formats/
__init__.py
wavread.py
effects/
__init__.py
echo.pyimport sound.effects.echo
sound.effects.echo.echofilter()
from sound.effects.echo import echofilter
echofilter()6.8 from package import * 与 __all__
# sound/effects/__init__.py
__all__ = ["echo", "surround", "reverse"]from sound.effects import * 只会拉 __all__ 里列出的符号(若定义了)。
6.9 相对导入(只能在包内模块里用)
# sound/effects/surround.py
from . import echo
from .. import formats- 入口脚本没有包内坐标 → 相对导入会炸;用
python -m pkg.module跑模块能减少路径问题。 - 循环导入:两个模块互相 import 时可能半成品名空间;解法包括延迟导入、拆公共子模块、依赖注入(与前端 circular dependency 同类难题)。
6.10 速记
| 点 | 规则 |
|---|---|
| 命名冲突 | as 别名 |
| 入口 | if __name__ == "__main__" |
| 找不到第三方 | venv 是否激活、python -m pip show 是否指向同一解释器 |
| 工程化 | pyproject.toml + 可编辑安装 |
权威延伸:6. Modules