Menu

Python 模块与导入:import、from import、pip 与包

Python 的模块系统如何工作:编写自己的模块、从模块中导入,以及用 pip 安装第三方包。

本页包含可运行的编辑器。编辑、运行,立即查看输出。

一个文件就是一个模块

当你的 Python 代码超出单个脚本的规模,你就会想把它拆分到多个文件里。Python 的模块系统很简单:任何 .py 文件都会自动成为一个模块,可以按名字导入。

假设你有一个文件 util.py:

# util.py
def greet(name):
    return f"Hello, {name}"

PI = 3.14159

在同一目录下的另一个文件 main.py 中,你可以使用它:

# main.py
import util

print(util.greet("Ada"))
print(util.PI)

运行 python3 main.py,Python 会找到 util.py,运行一次,并把顶层定义的所有东西(函数、变量、类)作为 util 模块的属性提供出来。

三种导入方式

导入整个模块。通过模块名访问其中的内容:

导入指定的名字。它们可以直接使用:

用别名导入。当模块名很长,或者两个模块重名时很有用:

import numpy as np
import pandas as pd

# Now use np.array(...), pd.DataFrame(...), etc.

还有第四种写法 from math import *,它会把所有东西都引入你的命名空间。除了在 REPL 里做实验,请避免使用它:它让你无法分辨一个名字来自哪里,还会造成悄无声息的命名冲突。

导入时会发生什么

在一个程序中,模块第一次被导入时,Python 会执行一次它的顶层代码。之后再导入同一个模块,返回的是已经加载好的版本。所以这段代码:

# setup.py
print("setup module loading...")
VALUE = 42
# main.py
import setup
import setup  # imported twice - but "loading" only prints once
print(setup.VALUE)

只会打印一次 "setup module loading..."。这一点很重要:如果你把副作用(比如打开文件或打印)放在模块顶层,它们会在导入时发生,而这通常不是你想要的。请把它们放进函数里。

标准库

Python 自带一个庞大的标准库。你已经见过其中几个了。下面是你会经常用到的:

  • math:平方根、正弦、对数,以及 pi 和 e 等常量。
  • random:随机数、随机选择、打乱顺序。
  • datetime:日期和时间。
  • json:读写 JSON。
  • os、os.path:文件系统路径和操作。
  • pathlib:现代的路径处理方式,通常比 os.path 更好用。
  • re:正则表达式。
  • collections:专用的集合类型(Counter、defaultdict、deque 等)。
  • itertools、functools:迭代器和函数的辅助工具。
  • csv:读写 CSV 文件。

标准库已经装好了,不需要 pip install。

第三方包与 pip

标准库没有覆盖到的功能,可以去 Python Package Index(PyPI)找,那里有几十万个包。用 pip 安装它们:

pip install requests
pip install pandas
pip install --upgrade requests
pip uninstall requests

安装之后,导入方式和其他模块一样:

import requests

response = requests.get("https://api.example.com/data")
print(response.status_code)

几条让包管理保持清爽的建议:

使用虚拟环境

把所有东西都装到全局会带来麻烦。不同的项目需要不同的版本;有些包依赖特定的 Python 版本;在某些系统上,全局安装还需要管理员权限。虚拟环境是一个只给单个项目用的独立 Python 环境:

python3 -m venv .venv
source .venv/bin/activate    # macOS/Linux
.venv\Scripts\activate       # Windows

pip install requests

当 venv 处于激活状态时,pip 会把包安装到项目文件夹里,而不是你的系统中。用完后用 deactivate 退出。

固定依赖版本

把已安装的包列表保存下来,这样其他人(包括以后的你)就能重建相同的环境:

pip freeze > requirements.txt

之后再运行:

pip install -r requirements.txt

Poetry、pipenv 和 uv 等工具用起来更顺手,但对于学习来说,简单的 pip + requirements.txt 流程完全够用。

编写自己的模块

当你有想在多个文件中复用的函数时,就把它们放进单独的模块。命名约定:

  • 文件名使用 lower_snake_case.py。
  • 模块级的函数和变量也使用 lower_snake_case。
  • 类使用 PascalCase。
# shopping.py
PRICES = {"apple": 0.50, "bread": 2.00}

def total(items):
    return sum(PRICES[item] for item in items)
# main.py
from shopping import total, PRICES

print(total(["apple", "bread"]))
print(PRICES)

如果同一文件夹里的两个文件互相导入,你可能会无意中造成循环导入。通常的解决办法是把共用的代码移到第三个文件中,让它们都导入这个文件。

包:装着模块的文件夹

当模块多了起来,就把它们组织成一个包,也就是一个包含 __init__.py 文件的文件夹:

myproject/
├── main.py
└── utils/
    ├── __init__.py
    ├── text.py
    └── numbers.py

然后:

from utils.text import slugify
from utils import numbers

print(slugify("Hello, World"))
print(numbers.mean([1, 2, 3]))

__init__.py 可以是空的;正是它的存在让 utils 成为一个包。新版 Python 也支持不带 __init__.py 的“命名空间包”,但刚开始学的时候,显式的写法更清楚。

导入出错时的简易检查清单

  • “ModuleNotFoundError: No module named X”。要么这个包没有安装,要么你运行 Python 用的解释器和执行 pip install 时的不是同一个。如果在 venv 中,请确认 venv 已激活。
  • “ImportError: cannot import name Y from X”。模块存在,但你要的名字不在里面。检查是否有拼写错误,并看看模块里实际有什么。
  • “Circular import”。两个模块互相导入。把共用的代码移到第三个模块中。

下一步:安装第三方包

靠自己的模块能走很远,但大多数实际项目还会引入 PyPI 上的库,比如 requests、pandas、某个测试框架。下一页介绍 pip、如何干净地安装包,以及如何记录项目的依赖。

常见问题

Python 中的模块是什么?

模块就是任意一个 .py 文件。Python 文件会自动成为模块,你可以按名字(不带 .py)导入它们。标准库是一大批内置模块,比如 math、json 和 datetime,每次安装 Python 都会自带。

import X 和 from X import Y 有什么区别?

import X 导入整个模块,你需要用 X.something 访问其中的内容。from X import Y 只把 Y 引入你的命名空间,所以可以直接用 Y。第一种写法更安全(不会命名冲突);第二种更简洁。

如何安装 Python 包?

在终端中运行 pip install package_name。pip 是 Python 的包管理器,新版 Python 安装时都会自带。为了让项目相互隔离,请先创建一个虚拟环境,这样安装的包就不会在项目之间互相影响。

Coddy 编程语言插图

和 Coddy 一起学编程

开始