Day 11:模块与包
🎯 学习目标:理解模块化编程,掌握导入方式、包管理、第三方库安装与打包
1. 模块介绍
1.1 什么是模块
模块就是一个 .py 文件。将代码按功能拆分到不同模块中,便于维护和复用。
mindmap project/ main.py 主程序 utils.py 工具函数模块 models.py 数据模型模块 config.py 配置模块
1.2 为什么要模块化
# utils.py(工具函数,100 行)
2. 导入方式
2.1 四种导入方式
# 方式一:import 模块名
import math
print(math.sqrt(16)) # 4.0
print(math.pi) # 3.141592653589793
# 方式二:import...as 别名
import numpy as np # 行业惯例
arr = np.array([1, 2, 3])
import pandas as pd # 行业惯例
df = pd.DataFrame({"a": [1, 2]})
# 方式三:from...import 部分内容
from math import sqrt, pi, sin, cos
print(sqrt(16)) # 不需要 math. 前缀
print(pi)
# 方式四:from...import *(不推荐!)
from math import * # 导入所有公开名字,污染命名空间
2.2 导入路径
import sys
# sys.path 决定了模块的搜索顺序
for path in sys.path:
print(path)
# 临时添加搜索路径
import sys
sys.path.append("/path/to/my/modules")
3. __all__ 与 __name__
3.1 __all__ 控制导出
# my_module.py
__all__ = ["public_func", "PublicClass"] # 白名单
def public_func():
"""可以被 from module import * 导入"""
return "公开函数"
def _internal_func():
"""_ 开头表示私有,但只是约定"""
return "内部函数"
class PublicClass:
pass
# 使用方
from my_module import *
# _internal_func ❌(不在 __all__ 中)
3.2 __name__ 判断运行方式
# utils.py
def helper():
return "工具函数"
print(f"utils.py 的 __name__ = {__name__}")
if __name__ == "__main__":
# 只有直接运行 python utils.py 时才执行
# 被 import 时不会执行
print("模块被直接运行")
print(helper())
__name__ 的值 | 场景 |
|---|---|
"__main__" | 直接运行 python xxx.py |
"模块名" | 被 import 导入 |
4. 包的创建与导入
包 = 包含 __init__.py 的文件夹:
mindmap mypackage/ 包 __init__.py 包的初始化文件 core.py 核心模块 utils.py 工具模块 subpackage/ 子包 __init__.py special.py
4.1 创建包
# mypackage/__init__.py
"""
mypackage - 我的 Python 包
"""
# 可以在 __init__.py 中提前导入常用内容
from .core import CoreClass
from .utils import helper
# 版本信息
__version__ = "1.0.0"
4.2 导入包
# 导入包内模块
import mypackage.core
from mypackage import utils
from mypackage.subpackage import special
# 如果 __init__.py 中已经导入了 CoreClass
from mypackage import CoreClass # 直接可用
# 在 mypackage/utils.py 中
from .core import CoreClass # . 表示当前包
from .. import other_package # .. 表示上级包
5. 安装第三方库
5.1 pip 基础操作
# 安装最新版
pip install requests
# 安装指定版本
pip install numpy==1.24.0
# 安装版本范围
pip install "django>=4.0,<5.0"
# 升级
pip install --upgrade requests
# 卸载
pip uninstall requests
# 查看已安装
pip list
pip show numpy # 查看某个包的详细信息
# 改用在 pypi.org 网站搜索
5.2 requirements.txt
# 导出当前环境所有包
pip freeze > requirements.txt
# 根据文件批量安装
pip install -r requirements.txt
requirements.txt 示例:
numpy==1.24.0
pandas>=2.0.0
requests
scikit-learn~=1.3.0 # ~= 表示兼容版本(1.3.x)
5.3 虚拟环境 venv
# 创建虚拟环境
python -m venv myenv
# 激活(Windows)
myenv\Scripts\activate
# 激活(Mac/Linux)
source myenv/bin/activate
# 激活后,pip install 只影响当前环境
pip install requests
# 退出
deactivate
为什么需要虚拟环境
项目 A 需要 Django 4.0,项目 B 需要 Django 3.2,全局安装会冲突。
虚拟环境为每个项目创建隔离的 Python 环境,互不影响。
6. 打包自己的代码
6.1 传统方式(setup.py)
mindmap my_project/ setup.py 打包配置 README.md LICENSE mylib/ 源代码 __init__.py core.py utils.py
# setup.py
from setuptools import setup, find_packages
setup(
name="mylib",
version="0.1.0",
author="你的名字",
description="我的 Python 库",
packages=find_packages(),
install_requires=[
"requests>=2.0",
"numpy>=1.20",
],
python_requires=">=3.8",
)
6.2 现代方式(pyproject.toml 推荐)
# pyproject.toml
[build-system]
requires = ["setuptools>=61.0"]
build-backend = "setuptools.backends._legacy:_Backend"
[project]
name = "mylib"
version = "0.1.0"
authors = [{name = "你的名字"}]
description = "我的 Python 库"
requires-python = ">=3.8"
dependencies = [
"requests>=2.0",
"numpy>=1.20",
]
[project.optional-dependencies]
dev = ["pytest", "ruff", "black"]
6.3 发布到 PyPI
# 安装打包工具
pip install build twine
# 构建
python -m build
# 上传到 PyPI(需要注册账号)
twine upload dist/*
速记卡(面试闪卡)
Q1:一句话讲清「Day 11:模块与包」到底是什么?
A:模块是一个 .py 文件,包是含 init.py 的文件夹,二者用来拆分和复用 Python 代码。
Q2:1. 模块介绍 —— 怎么理解?
A:像一个功能抽屉:模块(Module)就是一个 .py 文件,把代码按功能拆分到不同模块,便于维护和复用,避免一个文件写 5000 行难以维护。
Q3:2. 导入方式 —— 怎么理解?
A:像四种拿工具的方式:import 模块名(加前缀)、import…as 起别名(np/pd 惯例)、from…import 免前缀、from…import * 全导入(污染命名空间不推荐)。搜索靠 sys.path。
Q4:3. all 与 name —— 怎么理解?
A:像两个身份开关:all 是白名单控制 from x import * 导出哪些名;name 在直接运行时是 main、被导入时是模块名,if name==“main” 守卫只在直接运行才执行。
Q5:4. 包的创建与导入 —— 怎么理解?
A:像一个带门牌的文件夹:包(Package)是含 init.py 的文件夹,可在其中预导入常用内容;包内部用相对导入 . 当前包、.. 上级包。
Q6:核心速记主线有哪些?
-
模块是一个 .py 文件,用于按功能拆分复用代码;包是含 init.py 的文件夹
-
四种导入:import、import…as、from…import、from…import *(不推荐)
-
all 控制 * 导出白名单;name==“main” 守卫只在直接运行执行
-
包用相对导入(. 与 ..);第三方库用 pip 与 venv,打包用 pyproject.toml 发 PyPI
口诀
A:模块一个 .py 文件,包有 init 才成团
import as from 四式全,* 污染不推荐
all 管导出 name 辨运行
venv 隔离不打架,pyproject 发包欢