前端 Python 3.12

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 result

6.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

  1. 入口脚本目录-m 相关路径
  2. PYTHONPATH
  3. 标准库与 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.py
import 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

On this page