模块与包

翻译整理自 Python Tutorial - Modules 与 The Module Search Path。

1. 模块定义

一个 .py 文件就是一个模块。例如 fibo.py:

# fibo.py
def fib(n):
    a, b = 0, 1
    result = []
    for _ in range(n):
        result.append(a)
        a, b = b, a + b
    return result

引用:

import fibo
fibo.fib(10)

from fibo import fib
fib(10)

import fibo as f
f.fib(10)

from fibo import fib as fibonacci
fibonacci(10)

2. 模块搜索路径

Python 查找模块的顺序:

  1. 内置模块
  2. 输入脚本所在目录(或当前目录)
  3. PYTHONPATH 中的目录
  4. 标准库与已安装的第三方库(sys.path)
import sys
print(sys.path)

3. __name__ 与脚本入口

模块可以有"被导入"和"被执行"两种身份:

# fibo.py
if __name__ == "__main__":
    import sys
    print(fib(int(sys.argv[1])))
  • 直接 python fibo.py 10 → __name__ == "__main__" → 执行
  • import fibo → __name__ == "fibo" → 不执行

4. 标准库模块

import os
import sys
import json
import datetime
import math
import random
import itertools

5. 包 Package

包是模块的集合,目录下必须有 __init__.py(旧版本必需,新版可省略但建议保留):

mypackage/
├── __init__.py
├── utils.py
└── subpackage/
    ├── __init__.py
    └── net.py

引用:

import mypackage.utils
from mypackage import utils
from mypackage.subpackage import net

6. 相对导入

包内模块互引:

# mypackage/subpackage/net.py
from .. import utils       # 上一级
from . import something    # 同级

7. __all__ 控制导出

# fibo.py
__all__ = ["fib", "fib2"]

def fib(n): ...
def fib2(n): ...
def _helper(): ...   # 不会被 from fibo import * 导出

8. 包内 __main__.py

让包可直接执行:

mypackage/
├── __init__.py
└── __main__.py
python -m mypackage

9. 第三方包管理

pip install requests
pip install -r requirements.txt
pip list
pip freeze > requirements.txt
pip uninstall requests

升级 pip:

python -m pip install --upgrade pip

小结

模块、包、__name__ 是 Python 工程化的基础。下一章学习输入输出。