Python: 模块与包
当你写的代码越来越多,把所有内容塞进一个文件就不明智了。模块让你把代码拆分成多个文件,包让你把相关模块组织在一起。学会模块化编程,才算真正迈入"工程化"的门槛。
1. 什么是模块
在 Python 中,一个 .py 文件就是一个模块(module)。你可以用 import 导入其他模块中的功能:
▶ 示例:导入标准库模块
# 导入整个模块
import math
print(math.pi) # 3.141592653589793
print(math.sqrt(16)) # 4.0
# 导入特定函数
from random import randint
print(randint(1, 10)) # 1 到 10 之间的随机整数
# 导入多个
from datetime import datetime, timedelta
now = datetime.now()
print(now) # 当前时间
输出:
# 执行成功
Python 自带了大量的标准库模块——math、random、datetime、os、json……它们在你安装 Python 时就已经在了,直接 import 就能用。
2. 自定义模块
创建一个模块非常简单——写一个 .py 文件就行。
(1) my_tools.py
# 这是一个自定义模块:my_tools.py
def greet(name):
return f"你好,{name}"
def add(a, b):
return a + b
PI = 3.14159
(2) main.py(使用模块)
▶ 示例:导入并使用自定义模块
# 导入自定义模块
import my_tools
print(my_tools.greet("Alice")) # 你好,Alice
print(my_tools.add(5, 3)) # 8
print(my_tools.PI) # 3.14159
import 自己写的模块时提示"ModuleNotFoundError"——检查一下文件路径。
3. if __name__ == "__main__"
这是一个非常重要的 Python 模式——让一个文件既可以作为模块导入,也可以作为脚本直接运行:
▶ 示例:if name 双用途模式
# calculator.py
def add(a, b):
return a + b
def subtract(a, b):
return a - b
# 下面这段代码只在直接运行此文件时执行
if __name__ == "__main__":
print("测试计算器功能:")
print(f"3 + 5 = {add(3, 5)}")
print(f"10 - 4 = {subtract(10, 4)}")
输出:
测试计算器功能:
当你:
python calculator.py→ 会执行测试代码(__name__ == "__main__"为 True)- 在其他文件中
import calculator→ 测试代码不会执行(__name__是"calculator")
__name__ 变量。 直接运行时它是 "__main__",被导入时它是模块名。这个特性让同一个文件可以作为"库"和"脚本"双重使用。
4. 包(Package)
当模块多起来后,用包来组织——包就是一个包含 __init__.py 文件的目录:
my_package/
├── __init__.py ← 必须有这个文件(可以是空文件)
├── math_tools.py
└── string_tools.py
# math_tools.py
def multiply(a, b):
return a * b
def divide(a, b):
if b == 0:
return "除数不能为0"
return a / b
# string_tools.py
def reverse(text):
return text[::-1]
def count_vowels(text):
vowels = "aeiouAEIOU"
return sum(1 for c in text if c in vowels)
▶ 示例:使用包中的模块
# 使用包
from my_package import math_tools, string_tools
print(math_tools.multiply(3, 5)) # 15
print(string_tools.reverse("Python")) # nohtyP
5. 第三方库与 pip
Python 的强大很大程度上来自丰富的第三方库。用 pip 安装:
pip install requests # HTTP 请求库
pip install numpy # 数值计算
pip install pandas # 数据分析
pip install flask # Web 框架
(1) requirements.txt
当你把项目分享给别人时,需要告诉对方依赖了哪些第三方库。requirements.txt 就是干这个的:
requests==2.31.0
numpy==1.24.0
pandas==2.0.0
flask==3.0.0
对方拿到项目后,一条命令安装所有依赖:
pip install -r requirements.txt
(2) 生成 requirements.txt
pip freeze > requirements.txt
requirements.txt。这是 Python 项目的基本规范。如果你用的库版本更新了,别人 pip install -r requirements.txt 还能装到你当时用的版本,保证兼容性。
6. 常见应用场景
- 代码复用:把工具函数抽取到独立模块中,多个项目共用。
- 项目组织:用包按功能分层(如
models/、utils/、views/)。 - 依赖管理:用
requirements.txt管理第三方库版本。 - 脚本与库双用:用
if __name__ == "__main__"让文件既能被导入又能直接运行。
❓ 常见问题
import math 和 from math import pi 有什么区别?import math 导入整个模块,使用时必须写 math.pi。from math import pi 只导入 pi 这个变量,可以直接用 pi。前者更清晰(知道 pi 来自哪里),后者更简洁。项目中没有统一标准,但建议一个文件内保持一致。__init__.py 必须是空文件吗?__init__.py 在包被导入时执行,你可以在里面做初始化操作——比如定义 __all__ 控制 from package import * 的行为,或者直接在里面写工具函数。大多数简单项目中的 __init__.py 确实是空的。pip install 安装的库装到哪里了?Lib/site-packages/ 下。如果你在不同项目有不同依赖版本的需求,建议用虚拟环境(venv)——每个项目有独立的依赖目录,互不干扰。python -m venv myenv 创建,source myenv/bin/activate 激活。📖 小节
.py文件就是模块,import导入使用- 用
from 模块 import 名字可以只导入特定内容 if __name__ == "__main__"让文件既是模块又是脚本- 包是包含
__init__.py的目录,用于组织多个模块 pip install 包名安装第三方库requirements.txt记录项目依赖,pip install -r requirements.txt一次性安装
📝 作业
-
基础题(难度⭐):创建一个模块
geometry.py,包含两个函数circle_area(radius)和rectangle_area(width, height)。然后在另一个文件中导入并使用。 -
进阶题(难度⭐⭐):为
geometry.py添加if __name__ == "__main__"代码块,在里面测试你的函数。验证:直接运行时执行测试,被导入时测试不执行。 -
挑战题(难度⭐⭐⭐):创建一个包
string_utils/,包含两个模块:validators.py(验证函数:is_email()、is_phone())和transformers.py(转换函数:to_snake_case()、to_camel_case())。在包外写一个测试脚本导入并使用这些功能。