Python虚拟环境终极指南:新手从零到精通
Python虚拟环境终极指南:新手从零到精通(含实战案例)
前言:你是否遇到过这些困扰?
- 项目A需要Django 3.2,项目B需要Django 4.0,安装后互相冲突?
- 想尝试新库却担心污染系统环境?
- 换了台电脑,项目环境怎么都配不好?
- 看到别人用各种虚拟环境工具,不知道该选哪个?
别担心!本文将手把手教你使用venv、、conda、pipenv、poetry等主流工具,每个工具都配有完整的实战案例,让你从此告别依赖地狱!
📑 目录导航
- 第一章:虚拟环境基础概念
- 第二章:venv完全教程
- 第三章:uv完全教程
- 第四章:conda完全教程
- 第五章:pipenv完全教程
- 第六章:poetry完全教程
- 第七章:工具对比与选择建议
- 第八章:常见问题速查手册
第一章:虚拟环境基础概念
1.1 什么是虚拟环境?(新手必读)
🎯 简单理解
想象你有一台电脑,上面要运行多个Python项目:
不使用虚拟环境(❌ 错误做法):
你的电脑(系统Python)
├── 安装了 Django 3.2(为了项目A)
├── 安装了 Django 4.0(为了项目B)→ 冲突!
├── 安装了 requests 2.25.0
└── 安装了 requests 2.28.0 → 冲突!
结果:项目A和项目B都无法正常运行
使用虚拟环境(✅ 正确做法):
你的电脑
├── 项目A的虚拟环境
│ ├── Django 3.2
│ └── requests 2.25.0
│
├── 项目B的虚拟环境
│ ├── Django 4.0
│
└── 项目C的虚拟环境
├── requests 2.28.0
└── pandas
结果:每个项目独立运行,互不干扰!
📚 专业定义
虚拟环境是一个独立的Python运行环境,它包含:
- 独立的Python解释器:虽然指向系统Python,但有自己的配置
- 独立的site-packages目录:第三方库安装在这里
- 独立的依赖关系:不同项目的依赖完全隔离
1.2 为什么必须使用虚拟环境?
❌ 不使用虚拟环境的5大问题
问题1:版本冲突
# 场景:你有两个项目
# 项目A需要:Django 3.2 + requests 2.25.0
# 项目B需要:Django 4.0 + requests 2.28.0
# 如果不使用虚拟环境:
pip install Django==3.2 # 项目A正常
pip install Django==4.0 # 项目A报错!Django被升级了
pip install requests==2.28.0 # 项目B正常,但项目A可能不兼容
问题2:依赖污染
# 你在学习时安装了很多库
pip install numpy pandas matplotlib scikit-learn tensorflow pytorch
# 后来要做一个小项目,只需要requests
# 但你的环境里有一堆不需要的库,混乱且占用空间
问题3:难以复现
# 你在电脑A上开发项目,安装了很多库
# 换到电脑B,不知道具体安装了哪些版本
# 项目运行报错:ModuleNotFoundError
问题4:权限问题
# 在某些系统上,需要sudo才能安装包
sudo pip install package # 危险!可能破坏系统Python
问题5:团队协作困难
# 你的同事克隆了你的项目
# 但不知道需要安装哪些依赖
# 运行代码报错,浪费时间沟通
✅ 使用虚拟环境的5大好处
好处1:完全隔离
# 每个项目有独立的环境
project-a/venv # 只包含项目A需要的库
project-b/venv # 只包含项目B需要的库
# 互不干扰!
好处2:依赖清晰
# 可以清楚地知道项目需要哪些依赖
pip freeze > requirements.txt
# requirements.txt 记录了所有依赖和版本
好处3:易于复现
# 在任何机器上都能快速复现环境
pip install -r requirements.txt
# 一条命令搞定!
好处4:安全无忧
# 不需要sudo权限
pip install package # 安装到虚拟环境,安全!
好处5:团队协作友好
# 提交requirements.txt到git
# 同事克隆项目后,一条命令安装依赖
pip install -r requirements.txt
# 立即开始工作!
1.3 虚拟环境工作原理图解
┌─────────────────────────────────────────────────────────┐
│ 你的操作系统 │
│ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ 系统Python(全局) │ │
│ │ Python 3.10 │ │
│ │ site-packages/ │ │
│ │ ├── numpy │ │
│ │ └── pandas │ │
│ └─────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ 项目A的虚拟环境(venv) │ │
│ │ Python → 指向系统Python │ │
│ │ site-packages/ │ │
│ │ ├── Django 3.2 │ │
│ │ └── requests 2.25.0 │ │
│ └─────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ 项目B的虚拟环境(venv) │ │
│ │ Python → 指向系统Python │ │
│ │ site-packages/ │ │
│ │ ├── Django 4.0 │ │
│ │ └── requests 2.28.0 │ │
│ └─────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────┘
1.4 常见虚拟环境工具对比
| 工具 | 类型 | 安装难度 | 学习难度 | 速度 | 推荐指数 |
|---|---|---|---|---|---|
| venv | Python内置 | ⭐(无需安装) | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| uv | 第三方工具 | ⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| conda | 第三方工具 | ⭐⭐ | ⭐⭐⭐ | ⭐⭐ | ⭐⭐⭐⭐ |
| pipenv | 第三方工具 | ⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐ |
| poetry | 第三方工具 | ⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ |
1.5 新手学习路径建议
第一阶段(第1-2周)
├── 学习venv(Python内置,最简单)
├── 理解虚拟环境概念
└── 完成1-2个小项目
第二阶段(第3-4周)
├── 学习uv(速度快,现代化)
├── 学习依赖管理
└── 完成中等项目
第三阶段(持续)
├── 根据需求选择其他工具
├── 学习高级功能
└── 优化工作流程
第二章:venv完全教程(Python官方内置)
2.1 工具介绍
📖 什么是venv?
venv(virtual environment)是Python 3.3+版本官方内置的虚拟环境创建模块。
✅ 优点
- 无需安装:Python自带,开箱即用
- 官方支持:稳定可靠,长期维护
- 轻量级:只包含必要文件,占用空间小
- 学习成本低:命令简单,容易理解
❌ 缺点
- 功能基础:没有高级依赖管理功能
- 手动操作:需要手动管理requirements.txt
- 无依赖锁定:不会自动锁定依赖版本
🎯 适用场景
- ✅ Python初学者学习
- ✅ 简单的小项目
- ✅ 快速原型开发
- ✅ 不需要复杂依赖管理的项目
2.2 安装与准备
步骤1:检查Python版本
Windows系统:
# 打开CMD或PowerShell,输入:
python --version
# 输出示例:
# Python 3.10.12
# 如果显示"python不是内部或外部命令",请先安装Python
# 下载地址:https://www.python.org/downloads/
macOS/Linux系统:
# 打开终端,输入:
python3 --version
# 输出示例:
# Python 3.10.12
# 如果没有安装,使用包管理器安装:
# macOS(使用Homebrew):
brew install python3
# Ubuntu/Debian:
sudo apt update
sudo apt install python3 python3-venv
步骤2:确认venv可用
# 检查venv模块
python -m venv --help
# 如果显示帮助信息,说明venv可用
# 输出示例:
# usage: venv [-h] [--system-site-packages] [--symlinks | --copies] [--clear]
# [--upgrade-deps] [--prompt PROMPT] [--upgrade-deps]
# ENV_DIR [ENV_DIR ...]
# ...
⚠️ 常见问题
问题1:提示"找不到venv模块"
解决方案:
# Ubuntu/Debian系统需要单独安装venv
sudo apt install python3-venv
# 或使用完整版Python
sudo apt install python3-full
问题2:Python版本太低(< 3.3)
解决方案:
# 升级Python到3.3+版本
# 下载最新版:https://www.python.org/downloads/
2.3 基础操作教程
2.3.1 创建虚拟环境
📝 语法说明
python -m venv <环境名称>
python -m venv:调用venv模块<环境名称>:虚拟环境的文件夹名称
💡 实际操作
操作1:创建基础虚拟环境
# 在当前目录创建名为venv的虚拟环境
python -m venv venv
# 执行后会创建一个venv文件夹
操作2:创建自定义名称的虚拟环境
# 创建名为myenv的虚拟环境
python -m venv myenv
# 创建名为.env的虚拟环境(隐藏文件夹)
python -m venv .env
操作3:创建带系统包的虚拟环境
# 创建可以访问系统已安装包的虚拟环境
python -m venv --system-site-packages venv
📁 创建后的目录结构
venv/
├── Include/ # C头文件(编译扩展时使用)
├── Lib/ # Python库文件
│ └── site-packages/ # 第三方包安装位置
├── Scripts/ # 可执行脚本(Windows)
│ ├── activate # 激活脚本(CMD)
│ ├── activate.bat # 激活脚本(批处理)
│ ├── Activate.ps1 # 激活脚本(PowerShell)
│ ├── deactivate.bat # 退出脚本
│ ├── pip.exe # pip可执行文件
│ ├── pip3.exe
│ ├── python.exe # Python可执行文件
│ └── python3.exe
└── pyvenv.cfg # 虚拟环境配置文件
macOS/Linux系统的目录结构:
venv/
├── bin/ # 可执行脚本
│ ├── activate # 激活脚本
│ ├── activate.csh # C shell激活脚本
│ ├── activate.fish # Fish shell激活脚本
│ ├── python # Python可执行文件
│ └── pip # pip可执行文件
├── include/ # C头文件
├── lib/ # Python库文件
│ └── python3.10/
│ └── site-packages/
└── pyvenv.cfg # 配置文件
2.3.2 激活虚拟环境
📝 Windows系统激活
方法1:使用CMD(命令提示符)
# 进入项目目录
cd C:\Users\你的用户名\myproject
# 激活虚拟环境
venv\Scripts\activate
# 激活成功后,命令行前面会出现(venv)
(venv) C:\Users\你的用户名\myproject>
# ^^^^^
# 注意这个标识
方法2:使用PowerShell
# 激活虚拟环境
venv\Scripts\Activate.ps1
# 如果报错,见下面的解决方案
⚠️ PowerShell激活失败解决方案
错误信息:
无法加载文件 venv\Scripts\Activate.ps1,因为在此系统上禁止运行脚本
解决方案1:临时允许(推荐,每次打开PowerShell都需要执行)
Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process -Force
venv\Scripts\Activate.ps1
解决方案2:永久设置为RemoteSigned(更安全,只需执行一次)
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
venv\Scripts\Activate.ps1
解决方案3:使用CMD代替PowerShell
# 直接使用CMD,不会有这个问题
venv\Scripts\activate
📝 macOS/Linux系统激活
方法1:bash/zsh(默认shell)
# 激活虚拟环境
source venv/bin/activate
# 激活成功后,命令行前面会出现(venv)
(venv) user@computer:~/myproject$
# ^^^^^
方法2:fish shell
# 激活虚拟环境
source venv/bin/activate.fish
💡 激活成功的标志
激活成功后,你会看到:
- 命令行前面出现
(venv)标识 - Python路径指向虚拟环境
# 查看Python路径
where python # Windows
which python # macOS/Linux
# 输出示例(Windows):
# C:\Users\user\myproject\venv\Scripts\python.exe
# ^^^^^
# 确认路径包含venv
2.3.3 验证虚拟环境
操作1:查看Python版本和路径
# 查看Python版本
python --version
# 查看Python路径
where python # Windows
which python # macOS/Linux
# 查看pip版本
pip --version
操作2:查看已安装的包
# 列出所有已安装的包
pip list
# 输出示例:
# Package Version
# ---------- -------
# pip 23.1.2
# setuptools 65.5.0
# wheel 0.40.0
# 注意:新创建的虚拟环境只有这三个基础包
操作3:查看虚拟环境信息
# Windows
dir venv
# macOS/Linux
ls -la venv
# 查看配置文件
cat venv/pyvenv.cfg
# 输出示例:
# home = C:\Python310
# include-system-site-packages = false
# version = 3.10.12
2.3.4 安装和管理包
📦 安装包
操作1:安装单个包
# 安装requests库
pip install requests
# 安装过程会显示下载进度和依赖
# Collecting requests
# Downloading requests-2.28.0-py3-none-any.whl (62 kB)
# Installing collected packages: requests
# Successfully installed requests-2.28.0
操作2:安装指定版本
# 安装特定版本的requests
pip install requests==2.28.0
# 安装大于等于某个版本
pip install "requests>=2.28.0"
# 安装小于某个版本
pip install "requests<3.0.0"
操作3:安装多个包
# 一次性安装多个包
pip install requests pandas numpy matplotlib
# 或分别安装
pip install requests
pip install pandas
pip install numpy
操作4:从requirements.txt安装
# 从requirements.txt文件批量安装
pip install -r requirements.txt
🔍 查询包信息
操作1:列出已安装的包
# 列出所有包
pip list
# 列出过期的包
pip list --outdated
# 输出示例:
# Package Version Latest Type
# ---------- ------- ------ -----
# pip 23.1.2 23.1.2 wheel
# requests 2.28.0 2.31.0 wheel # ← 有新版本
操作2:显示包详细信息
# 查看requests包的详细信息
pip show requests
# 输出示例:
# Name: requests
# Version: 2.28.0
# Summary: Python HTTP for Humans.
# Home-page: https://requests.readthedocs.io
# Author: Kenneth Reitz
# Author-email: me@kennethreitz.org
# License: Apache 2.0
# Location: c:\users\user\myproject\venv\lib\site-packages
# Requires: certifi, charset-normalizer, idna, urllib3
# Required-by:
操作3:检查包是否安装
# 检查requests是否安装
pip show requests
# 如果已安装,显示详细信息
# 如果未安装,显示:WARNING: Package(s) not found
🔄 更新和卸载包
操作1:更新包
# 更新requests到最新版本
pip install --upgrade requests
# 或使用简写
pip install -U requests
操作2:卸载包
# 卸载requests
pip uninstall requests
# 会提示确认:
# Found existing installation: requests 2.28.0
# Uninstalling requests-2.28.0:
# Would remove:
# c:\users\user\myproject\venv\lib\site-packages\requests\*
# Proceed (y/n)? y
# 自动确认(不提示)
pip uninstall requests -y
操作3:批量卸载
# 从requirements.txt卸载所有包
pip uninstall -r requirements.txt -y
⚙️ pip高级操作
操作1:升级pip
# 升级pip到最新版本
pip install --upgrade pip
操作2:查看pip配置
# 查看pip配置信息
pip config list
# 查看pip安装路径
pip show pip
操作3:清理缓存
# 查看缓存信息
pip cache info
# 清理缓存
pip cache purge
2.3.5 导出和安装依赖
📝 导出依赖列表
操作1:导出所有依赖
# 将当前环境的所有依赖导出到requirements.txt
pip freeze > requirements.txt
# 查看requirements.txt内容
cat requirements.txt # Windows: type requirements.txt
# 输出示例:
# certifi==2022.12.7
# charset-normalizer==2.1.1
# idna==3.4
# requests==2.28.0
# urllib3==1.26.13
操作2:导出指定包
# 只导出requests及其依赖
pip freeze | grep requests > requirements.txt
# 或手动创建requirements.txt
echo "requests==2.28.0" > requirements.txt
echo "pandas==1.5.3" >> requirements.txt
📥 安装依赖
操作1:从requirements.txt安装
# 安装requirements.txt中的所有包
pip install -r requirements.txt
# 安装过程:
# Reading requirements.txt
# Collecting requests==2.28.0
# Collecting pandas==1.5.3
# ...
# Successfully installed requests-2.28.0 pandas-1.5.3 ...
操作2:只安装核心依赖(跳过依赖的依赖)
# 安装时不安装依赖的依赖
pip install -r requirements.txt --no-deps
操作3:升级requirements.txt中的包
# 升级requirements.txt中的所有包
pip install -r requirements.txt --upgrade
💡 requirements.txt最佳实践
推荐的requirements.txt格式:
# 核心依赖(指定版本)
requests==2.28.0
pandas==1.5.3
numpy==1.23.5
# 可选依赖(注释说明)
# matplotlib==3.7.0 # 可视化(可选)
# seaborn==0.12.2 # 统计图表(可选)
版本号说明:
# 精确版本
package==1.0.0
# 大于等于
package>=1.0.0
# 小于
package<2.0.0
# 范围
package>=1.0.0,<2.0.0
# 兼容版本(推荐)
package~=1.0.0 # 等同于 >=1.0.0, <1.1.0
2.3.6 退出虚拟环境
📝 操作方法
# 退出虚拟环境
deactivate
# 退出后,命令行前的(venv)标识会消失
C:\Users\user\myproject>
# (venv)消失了
💡 验证退出
# 查看Python路径
where python # Windows
which python # macOS/Linux
# 输出示例(Windows):
# C:\Python310\python.exe
# ^^^^^^^^^^^
# 现在指向系统Python,不是虚拟环境了
2.3.7 删除虚拟环境
📝 操作方法
Windows系统:
# 方法1:使用rmdir命令
rmdir /s /q venv
# 方法2:使用rd命令
rd /s /q venv
# 方法3:直接在文件管理器中删除venv文件夹
macOS/Linux系统:
# 删除虚拟环境目录
rm -rf venv
⚠️ 注意事项
-
确保已退出虚拟环境
# 先退出 deactivate # 再删除 rm -rf venv -
删除前确认
# 查看虚拟环境内容 ls venv # macOS/Linux dir venv # Windows # 确认无误后再删除 -
不要删除系统Python
# 只删除项目目录下的venv文件夹 # 不要删除C:\Python310或/usr/bin/python
2.4 实战案例1:Web爬虫项目
📋 案例背景
创建一个简单的网页爬虫项目,需要使用以下库:
requests:发送HTTP请求beautifulsoup4:解析HTMLlxml:HTML解析器
🎯 学习目标
通过这个案例,你将学会:
- 创建和激活虚拟环境
- 安装多个依赖包
- 编写Python脚本
- 导出依赖列表
- 在其他机器上复现环境
📝 完整操作步骤
步骤1:创建项目目录
Windows:
# 创建项目目录
mkdir web_scraper
cd web_scraper
# 查看当前目录
cd
macOS/Linux:
# 创建项目目录
mkdir web_scraper
cd web_scraper
# 查看当前目录
pwd
步骤2:创建虚拟环境
# 创建虚拟环境
python -m venv venv
# 查看创建的文件
dir venv # Windows
ls venv # macOS/Linux
步骤3:激活虚拟环境
Windows(CMD):
venv\Scripts\activate
Windows(PowerShell):
venv\Scripts\Activate.ps1
macOS/Linux:
source venv/bin/activate
验证激活:
# 查看Python路径
where python # Windows
which python # macOS/Linux
# 应该看到路径包含venv
步骤4:安装依赖
# 安装requests
pip install requests
# 安装beautifulsoup4和lxml
pip install beautifulsoup4 lxml
# 或一次性安装
pip install requests beautifulsoup4 lxml
查看安装结果:
# 列出已安装的包
pip list
# 输出示例:
# Package Version
# -------------- -------
# beautifulsoup4 4.11.1
# certifi 2022.12.7
# charset-normalizer 2.1.1
# idna 3.4
# lxml 4.9.2
# pip 23.1.2
# requests 2.28.0
# setuptools 65.5.0
# soupsieve 2.3.2.post1
# urllib3 1.26.13
# wheel 0.40.0
步骤5:创建爬虫脚本
创建文件 scraper.py:
# scraper.py
import requests
from bs4 import BeautifulSoup
def scrape_title(url):
"""
获取网页标题
Args:
url: 网页URL
Returns:
str: 网页标题
"""
try:
# 发送HTTP请求
response = requests.get(url, timeout=10)
response.raise_for_status() # 检查请求是否成功
# 解析HTML
soup = BeautifulSoup(response.text, 'lxml')
# 提取标题
title = soup.title.string if soup.title else 'No title'
return title.strip()
except requests.exceptions.RequestException as e:
return f'Error: {e}'
except Exception as e:
return f'Error: {e}'
def scrape_links(url):
"""
获取网页所有链接
Args:
url: 网页URL
Returns:
list: 链接列表
"""
try:
response = requests.get(url, timeout=10)
response.raise_for_status()
soup = BeautifulSoup(response.text, 'lxml')
# 提取所有链接
links = []
for link in soup.find_all('a', href=True):
links.append({
'text': link.text.strip(),
'href': link['href']
})
return links
except Exception as e:
print(f'Error: {e}')
return []
if __name__ == '__main__':
# 测试URL
test_url = 'https://www.example.com'
print('=' * 50)
print('网页爬虫示例')
print('=' * 50)
# 获取标题
print(f'\n正在获取: {test_url}')
title = scrape_title(test_url)
print(f'网页标题: {title}')
# 获取链接
print(f'\n获取链接...')
links = scrape_links(test_url)
print(f'找到 {len(links)} 个链接')
# 显示前5个链接
print('\n前5个链接:')
for i, link in enumerate(links[:5], 1):
print(f'{i}. {link["text"][:50]} -> {link["href"]}')
print('\n完成!')
步骤6:运行爬虫
# 运行爬虫脚本
python scraper.py
# 输出示例:
# ==================================================
# 网页爬虫示例
# ==================================================
#
# 正在获取: https://www.example.com
# 网页标题: Example Domain
#
# 获取链接...
# 找到 1 个链接
#
# 前5个链接:
# 1. More information... -> https://www.iana.org/domains/example
#
# 完成!
步骤7:导出依赖
# 导出依赖到requirements.txt
pip freeze > requirements.txt
# 查看requirements.txt内容
type requirements.txt # Windows
cat requirements.txt # macOS/Linux
requirements.txt内容:
beautifulsoup4==4.11.1
certifi==2022.12.7
charset-normalizer==2.1.1
idna==3.4
lxml==4.9.2
requests==2.28.0
soupsieve==2.3.2.post1
urllib3==1.26.13
步骤8:创建.gitignore
创建文件 .gitignore:
# Python
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
# 虚拟环境
venv/
env/
ENV/
.venv/
# IDE
.vscode/
.idea/
*.swp
*.swo
# 其他
*.log
.DS_Store
步骤9:在其他机器上复现环境
场景:你的同事克隆了你的项目,需要配置环境
# 1. 克隆项目
git clone https://github.com/yourusername/web_scraper.git
cd web_scraper
# 2. 创建虚拟环境
python -m venv venv
# 3. 激活虚拟环境
# Windows
venv\Scripts\activate
# macOS/Linux
source venv/bin/activate
# 4. 安装依赖
pip install -r requirements.txt
# 5. 运行项目
python scraper.py
# 完成!环境完全一致
📁 最终项目结构
web_scraper/
├── venv/ # 虚拟环境(不提交到git)
├── scraper.py # 爬虫脚本
├── requirements.txt # 依赖列表
└── .gitignore # Git忽略文件
💡 案例总结
通过这个案例,你学会了:
- ✅ 创建项目目录和虚拟环境
- ✅ 激活虚拟环境
- ✅ 安装多个依赖包
- ✅ 编写和运行Python脚本
- ✅ 导出依赖列表
- ✅ 创建.gitignore文件
- ✅ 在其他机器上复现环境
2.5 实战案例2:数据分析项目
📋 案例背景
创建一个数据分析项目,需要使用以下库:
pandas:数据处理numpy:数值计算matplotlib:数据可视化seaborn:统计图表
🎯 学习目标
通过这个案例,你将学会:
- 安装数据分析相关库
- 创建数据分析脚本
- 生成图表
- 使用Jupyter Notebook(可选)
📝 完整操作步骤
步骤1:创建项目
# 创建项目目录
mkdir data_analysis
cd data_analysis
# 创建虚拟环境
python -m venv venv
# 激活虚拟环境
# Windows
venv\Scripts\activate
# macOS/Linux
source venv/bin/activate
步骤2:安装数据分析库
# 安装核心库
pip install pandas numpy matplotlib seaborn
# 查看安装结果
pip list
安装说明:
pandas:会自动安装numpy作为依赖matplotlib:绘图库seaborn:基于matplotlib的统计图表库
步骤3:创建分析脚本
创建文件 analysis.py:
# analysis.py
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
# 设置中文字体(可选)
plt.rcParams['font.sans-serif'] = ['SimHei'] # Windows
# plt.rcParams['font.sans-serif'] = ['Arial Unicode MS'] # macOS
plt.rcParams['axes.unicode_minus'] = False
def create_sample_data():
"""创建示例数据"""
np.random.seed(42)
# 创建销售数据
data = {
'月份': ['1月', '2月', '3月', '4月', '5月', '6月',
'7月', '8月', '9月', '10月', '11月', '12月'],
'销售额': np.random.randint(100, 300, 12),
'成本': np.random.randint(50, 150, 12),
'利润': None # 稍后计算
}
df = pd.DataFrame(data)
# 计算利润
df['利润'] = df['销售额'] - df['成本']
return df
def analyze_data(df):
"""分析数据"""
print('=' * 60)
print('数据分析报告')
print('=' * 60)
# 显示数据
print('\n【原始数据】')
print(df.to_string(index=False))
# 统计信息
print('\n【统计信息】')
print(df.describe())
# 总销售额、成本、利润
total_sales = df['销售额'].sum()
total_cost = df['成本'].sum()
total_profit = df['利润'].sum()
print(f'\n【年度汇总】')
print(f'总销售额: {total_sales:,} 元')
print(f'总成本: {total_cost:,} 元')
print(f'总利润: {total_profit:,} 元')
print(f'利润率: {total_profit/total_sales*100:.2f}%')
# 最佳月份
best_month = df.loc[df['利润'].idxmax()]
print(f'\n【最佳月份】')
print(f'{best_month["月份"]}: 销售额 {best_month["销售额"]:,} 元, 利润 {best_month["利润"]:,} 元')
def plot_data(df):
"""绘制图表"""
# 创建图表
fig, axes = plt.subplots(2, 2, figsize=(14, 10))
# 图1:销售额趋势
axes[0, 0].plot(df['月份'], df['销售额'], marker='o', linewidth=2, markersize=8)
axes[0, 0].set_title('月度销售额趋势', fontsize=14, fontweight='bold')
axes[0, 0].set_xlabel('月份')
axes[0, 0].set_ylabel('销售额(元)')
axes[0, 0].grid(True, alpha=0.3)
axes[0, 0].tick_params(axis='x', rotation=45)
# 图2:销售额、成本、利润对比
x = np.arange(len(df))
width = 0.25
axes[0, 1].bar(x - width, df['销售额'], width, label='销售额', color='steelblue')
axes[0, 1].bar(x, df['成本'], width, label='成本', color='coral')
axes[0, 1].bar(x + width, df['利润'], width, label='利润', color='lightgreen')
axes[0, 1].set_title('销售额、成本、利润对比', fontsize=14, fontweight='bold')
axes[0, 1].set_xlabel('月份')
axes[0, 1].set_ylabel('金额(元)')
axes[0, 1].set_xticks(x)
axes[0, 1].set_xticklabels(df['月份'])
axes[0, 1].legend()
axes[0, 1].tick_params(axis='x', rotation=45)
axes[0, 1].grid(True, alpha=0.3, axis='y')
# 图3:利润分布
axes[1, 0].hist(df['利润'], bins=10, edgecolor='black', color='skyblue', alpha=0.7)
axes[1, 0].set_title('利润分布', fontsize=14, fontweight='bold')
axes[1, 0].set_xlabel('利润(元)')
axes[1, 0].set_ylabel('频数')
axes[1, 0].grid(True, alpha=0.3, axis='y')
# 图4:累计利润
cumulative_profit = df['利润'].cumsum()
axes[1, 1].fill_between(df['月份'], cumulative_profit, alpha=0.3, color='green')
axes[1, 1].plot(df['月份'], cumulative_profit, marker='o', linewidth=2, color='green')
axes[1, 1].set_title('累计利润趋势', fontsize=14, fontweight='bold')
axes[1, 1].set_xlabel('月份')
axes[1, 1].set_ylabel('累计利润(元)')
axes[1, 1].grid(True, alpha=0.3)
axes[1, 1].tick_params(axis='x', rotation=45)
plt.tight_layout()
plt.savefig('sales_analysis.png', dpi=300, bbox_inches='tight')
print('\n图表已保存为 sales_analysis.png')
def main():
"""主函数"""
# 创建数据
df = create_sample_data()
# 分析数据
analyze_data(df)
# 绘制图表
plot_data(df)
print('\n分析完成!')
if __name__ == '__main__':
main()
步骤4:运行分析
# 运行分析脚本
python analysis.py
# 输出示例:
# ============================================================
# 数据分析报告
# ============================================================
#
# 【原始数据】
# 月份 销售额 成本 利润
# 1月 172 98 74
# 2月 247 68 179
# 3月 102 55 47
# 4月 218 88 130
# 5月 246 59 187
# 6月 235 84 151
# 7月 279 95 184
# 8月 147 51 96
# 9月 114 72 42
# 10月 289 78 211
# 11月 129 68 61
# 12月 189 92 97
#
# 【统计信息】
# 销售额 成本 利润
# count 12.000000 12.000000 12.000000
# mean 197.500000 75.833333 121.666667
# std 62.324960 16.823560 56.823560
# min 102.000000 51.000000 42.000000
# 25% 138.500000 61.500000 61.500000
# 50% 198.500000 75.000000 114.000000
# 75% 246.250000 88.250000 179.250000
# max 289.000000 98.000000 211.000000
#
# 【年度汇总】
# 总销售额: 2,370 元
# 总成本: 910 元
# 总利润: 1,460 元
# 利润率: 61.60%
#
# 【最佳月份】
# 10月: 销售额 289 元, 利润 211 元
#
# 图表已保存为 sales_analysis.png
#
# 分析完成!
步骤5:查看生成的图表
# 查看生成的图表文件
dir sales_analysis.png # Windows
ls -lh sales_analysis.png # macOS/Linux
# 用图片查看器打开
# Windows: start sales_analysis.png
# macOS: open sales_analysis.png
# Linux: xdg-open sales_analysis.png
步骤6:使用Jupyter Notebook(可选)
安装Jupyter:
# 安装Jupyter
pip install jupyter
# 启动Jupyter
jupyter notebook
# 浏览器会自动打开,可以创建notebook进行交互式分析
在Jupyter中使用:
# 在Jupyter notebook中
import pandas as pd
import matplotlib.pyplot as plt
# 创建数据
df = pd.DataFrame({
'A': [1, 2, 3],
'B': [4, 5, 6]
})
# 显示数据
df
# 绘图
df.plot()
plt.show()
步骤7:导出依赖
# 导出依赖
pip freeze > requirements.txt
# 查看内容
type requirements.txt # Windows
cat requirements.txt # macOS/Linux
requirements.txt内容:
contourpy==1.0.7
cycler==0.11.0
fonttools==4.38.0
kiwisolver==1.4.4
matplotlib==3.7.1
numpy==1.24.2
pandas==1.5.3
Pillow==9.4.0
pyparsing==3.0.9
python-dateutil==2.8.2
pytz==2022.7.1
seaborn==0.12.2
six==1.16.0
📁 最终项目结构
data_analysis/
├── venv/ # 虚拟环境
├── analysis.py # 分析脚本
├── sales_analysis.png # 生成的图表
├── requirements.txt # 依赖列表
└── .gitignore # Git忽略文件
💡 案例总结
通过这个案例,你学会了:
- ✅ 安装数据分析相关库
- ✅ 创建数据分析脚本
- ✅ 使用pandas处理数据
- ✅ 使用matplotlib和seaborn绘制图表
- ✅ 使用Jupyter Notebook(可选)
- ✅ 导出依赖列表
2.6 venv常用命令速查表
📋 创建和激活
| 命令 | 说明 |
|---|---|
python -m venv venv |
创建虚拟环境 |
python -m venv --clear venv |
清除并重新创建 |
venv\Scripts\activate |
Windows激活 |
source venv/bin/activate |
macOS/Linux激活 |
deactivate |
退出虚拟环境 |
📦 包管理
| 命令 | 说明 |
|---|---|
pip install package |
安装包 |
pip install package==1.0.0 |
安装指定版本 |
pip install -r requirements.txt |
批量安装 |
pip uninstall package |
卸载包 |
pip list |
列出已安装的包 |
pip show package |
显示包信息 |
pip list --outdated |
列出过期的包 |
pip install --upgrade package |
升级包 |
📝 依赖管理
| 命令 | 说明 |
|---|---|
pip freeze > requirements.txt |
导出依赖 |
pip install -r requirements.txt |
安装依赖 |
pip check |
检查依赖冲突 |
🔧 其他
| 命令 | 说明 |
|---|---|
python --version |
查看Python版本 |
pip --version |
查看pip版本 |
where python |
查看Python路径(Windows) |
which python |
查看Python路径(macOS/Linux) |
2.7 venv最佳实践
✅ 推荐做法
-
每个项目使用独立的虚拟环境
cd project-a python -m venv venv cd project-b python -m venv venv -
使用标准命名
# 推荐 python -m venv venv python -m venv .venv # 不推荐 python -m venv my_virtual_environment_123 -
及时更新pip
pip install --upgrade pip -
使用requirements.txt
pip freeze > requirements.txt -
创建.gitignore
venv/ .venv/ __pycache__/ *.pyc -
在README中说明环境配置
## 环境配置 ```bash python -m venv venv source venv/bin/activate # Windows: venv\Scripts\activate pip install -r requirements.txt
❌ 避免做法
-
不要在系统Python中安装包
# ❌ 错误 sudo pip install package # ✅ 正确 python -m venv venv source venv/bin/activate pip install package -
不要提交虚拟环境到git
# .gitignore venv/ .venv/ -
不要混用不同Python版本
# ❌ 错误 python3.9 -m venv venv python3.10 -m venv venv # 覆盖了上面的 # ✅ 正确 python3.9 -m venv venv39 python3.10 -m venv venv310 -
不要在虚拟环境中使用sudo
# ❌ 错误 sudo pip install package # ✅ 正确 pip install package
第三章:uv完全教程(新一代极速工具)
3.1 工具介绍
📖 什么是uv?
uv是由Astral团队(Ruff开发者)开发的极速Python包管理器和虚拟环境工具,使用Rust编写。
✅ 优点
- 极速安装:比pip快10-100倍
- 完全兼容pip:可以无缝替换pip
- 一体化工具:虚拟环境+包管理
- 自动依赖锁定:类似poetry的依赖解析
- 智能缓存:重复安装更快
- 现代化设计:用户体验优秀
❌ 缺点
- 相对较新:2024年发布,生态还在发展
- 需要安装:不像venv那样内置
- 某些高级功能:可能不如poetry完善
🎯 适用场景
- ✅ 追求安装速度的项目
- ✅ 大型项目(依赖多)
- ✅ 需要频繁切换环境
- ✅ CI/CD环境
- ✅ 现代化Python开发
3.2 安装与准备
步骤1:安装uv
Windows安装
方法1:使用官方安装脚本(推荐)
# 在PowerShell中执行
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
方法2:使用pip安装
pip install uv
方法3:使用pipx安装(推荐)
pip install pipx
pipx install uv
macOS/Linux安装
方法1:使用官方安装脚本(推荐)
curl -LsSf https://astral.sh/uv/install.sh | sh
方法2:使用pip安装
pip install uv
方法3:使用pipx安装(推荐)
pip install pipx
pipx install uv
步骤2:验证安装
# 检查uv版本
uv --version
# 输出示例:
# uv 0.1.0
# 查看帮助
uv --help
步骤3:配置uv(可选)
设置镜像源(加速下载)
# 设置清华镜像源
uv pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
# 查看配置
uv pip config list
# 输出示例:
# [global]
# index-url = https://pypi.tuna.tsinghua.edu.cn/simple
其他配置
# 设置缓存目录
uv pip config set global.cache-dir /path/to/cache
# 设置超时时间
uv pip config set global.timeout 60
3.3 基础操作教程
3.3.1 创建虚拟环境
📝 语法说明
uv venv [选项]
💡 实际操作
操作1:创建基础虚拟环境
# 创建虚拟环境(自动检测Python版本)
uv venv
# 默认创建.venv目录
操作2:指定Python版本
# 使用Python 3.11
uv venv --python 3.11
# 使用特定Python路径
uv venv --python /usr/bin/python3.11
操作3:自定义环境名称
# 创建名为venv的虚拟环境
uv venv venv
# 创建名为myenv的虚拟环境
uv venv myenv
操作4:设置提示符
# 设置环境提示符
uv venv --prompt myproject
操作5:预装常用包
# 创建并预装pip、setuptools、wheel
uv venv --seed
📁 创建后的目录结构
.venv/
├── bin/ # macOS/Linux
│ ├── activate
│ ├── python
│ └── pip
├── Scripts/ # Windows
│ ├── activate.bat
│ ├── python.exe
│ └── pip.exe
└── pyvenv.cfg
3.3.2 激活虚拟环境
Windows系统
# 激活虚拟环境
.venv\Scripts\activate
# 或
.venv\Scripts\activate.bat
macOS/Linux系统
# 激活虚拟环境
source .venv/bin/activate
验证激活
# 查看Python路径
where python # Windows
which python # macOS/Linux
# 应该看到路径包含.venv
3.3.3 使用uv管理包
📦 安装包
操作1:安装单个包
# 安装requests
uv pip install requests
# 速度比pip快很多!
操作2:安装指定版本
# 安装特定版本
uv pip install requests==2.28.0
# 安装大于等于某个版本
uv pip install "requests>=2.28.0"
操作3:安装多个包
# 一次性安装多个包
uv pip install requests pandas numpy matplotlib
操作4:从requirements.txt安装
# 从requirements.txt安装
uv pip install -r requirements.txt
# 速度比pip快很多!
操作5:从Git安装
# 从GitHub安装
uv pip install git+https://github.com/user/repo.git
# 安装特定分支
uv pip install git+https://github.com/user/repo.git@branch
# 安装特定提交
uv pip install git+https://github.com/user/repo.git@commit_hash
操作6:从本地路径安装
# 从本地目录安装
uv pip install ./local-package
# 从本地压缩包安装
uv pip install ./package-1.0.0.tar.gz
🔍 查询包信息
操作1:列出已安装的包
# 列出所有包
uv pip list
# 输出示例:
# Package Version
# ---------- -------
# pip 23.1.2
# requests 2.28.0
操作2:显示包详细信息
# 显示包信息
uv pip show requests
# 输出示例:
# Name: requests
# Version: 2.28.0
# Summary: Python HTTP for Humans.
# ...
操作3:列出过期的包
# 列出过期的包
uv pip list --outdated
🔄 更新和卸载包
操作1:更新包
# 更新到最新版本
uv pip install --upgrade requests
# 或使用简写
uv pip install -U requests
操作2:卸载包
# 卸载包
uv pip uninstall requests
📝 导出依赖
# 导出依赖
uv pip freeze > requirements.txt
# 查看内容
cat requirements.txt
3.3.4 uv的高级功能
依赖解析
# 解析依赖但不安装
uv pip resolve requests pandas
# 输出依赖树
uv pip tree
# 输出示例:
# requests==2.28.0
# ├── certifi>=2017.4.17
# ├── charset-normalizer<4,>=2
# ├── idna<4,>=2.5
# └── urllib3<1.27,>=1.21.1
缓存管理
# 查看缓存信息
uv cache dir
# 清理缓存
uv cache clean
# 清理特定包的缓存
uv cache clean requests
并行安装
# uv默认并行安装,速度更快
# 可以通过环境变量控制
export UV_CONCURRENT_DOWNLOADS=10
3.4 实战案例1:FastAPI Web项目
📋 案例背景
使用uv创建一个FastAPI Web应用,包含:
- FastAPI:Web框架
- Uvicorn:ASGI服务器
- SQLAlchemy:ORM
- Pydantic:数据验证
🎯 学习目标
通过这个案例,你将学会:
- 使用uv创建虚拟环境
- 快速安装多个依赖
- 创建FastAPI应用
- 运行和测试API
📝 完整操作步骤
步骤1:创建项目
# 创建项目目录
mkdir fastapi_project
cd fastapi_project
# 使用uv创建虚拟环境
uv venv --python 3.11
# 激活虚拟环境
# Windows
.venv\Scripts\activate
# macOS/Linux
source .venv/bin/activate
步骤2:安装依赖
# 安装FastAPI和相关依赖
uv pip install fastapi uvicorn sqlalchemy pydantic
# 安装开发依赖
uv pip install pytest httpx
# 查看安装结果
uv pip list
安装速度对比:
使用pip:可能需要30-60秒
使用uv:只需要3-5秒!
步骤3:创建FastAPI应用
创建文件 main.py:
# main.py
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel, Field
from typing import List, Optional
from datetime import datetime
app = FastAPI(
title="任务管理API",
description="一个简单的任务管理API",
version="1.0.0"
)
# 数据模型
class TaskBase(BaseModel):
title: str = Field(..., min_length=1, max_length=100, description="任务标题")
description: Optional[str] = Field(None, description="任务描述")
priority: int = Field(1, ge=1, le=5, description="优先级(1-5)")
class Task(TaskBase):
id: int
created_at: datetime
completed: bool = False
class Config:
json_schema_extra = {
"example": {
"id": 1,
"title": "完成项目文档",
"description": "编写项目README和API文档",
"priority": 3,
"created_at": "2024-01-01T00:00:00",
"completed": False
}
}
class TaskCreate(TaskBase):
pass
class TaskUpdate(BaseModel):
title: Optional[str] = Field(None, min_length=1, max_length=100)
description: Optional[str] = None
priority: Optional[int] = Field(None, ge=1, le=5)
completed: Optional[bool] = None
# 模拟数据库
tasks_db: List[Task] = []
task_id_counter = 0
# 根路径
@app.get("/", tags=["根路径"])
def read_root():
"""API根路径"""
return {
"message": "欢迎使用任务管理API",
"version": "1.0.0",
"docs": "/docs",
"redoc": "/redoc"
}
# 获取所有任务
@app.get("/tasks", response_model=List[Task], tags=["任务"])
def get_tasks(
skip: int = 0,
limit: int = 10,
completed: Optional[bool] = None
):
"""获取任务列表"""
tasks = tasks_db
# 过滤
if completed is not None:
tasks = [t for t in tasks if t.completed == completed]
# 分页
return tasks[skip:skip + limit]
# 获取单个任务
@app.get("/tasks/{task_id}", response_model=Task, tags=["任务"])
def get_task(task_id: int):
"""获取单个任务"""
for task in tasks_db:
if task.id == task_id:
return task
raise HTTPException(status_code=404, detail="任务未找到")
# 创建任务
@app.post("/tasks", response_model=Task, status_code=201, tags=["任务"])
def create_task(task: TaskCreate):
"""创建新任务"""
global task_id_counter
task_id_counter += 1
new_task = Task(
id=task_id_counter,
**task.dict(),
created_at=datetime.now()
)
tasks_db.append(new_task)
return new_task
# 更新任务
@app.put("/tasks/{task_id}", response_model=Task, tags=["任务"])
def update_task(task_id: int, task: TaskUpdate):
"""更新任务"""
for i, existing_task in enumerate(tasks_db):
if existing_task.id == task_id:
update_data = task.dict(exclude_unset=True)
tasks_db[i] = existing_task.copy(update=update_data)
return tasks_db[i]
raise HTTPException(status_code=404, detail="任务未找到")
# 删除任务
@app.delete("/tasks/{task_id}", tags=["任务"])
def delete_task(task_id: int):
"""删除任务"""
for i, task in enumerate(tasks_db):
if task.id == task_id:
tasks_db.pop(i)
return {"message": "任务已删除", "id": task_id}
raise HTTPException(status_code=404, detail="任务未找到")
# 统计信息
@app.get("/stats", tags=["统计"])
def get_stats():
"""获取统计信息"""
total = len(tasks_db)
completed = len([t for t in tasks_db if t.completed])
pending = total - completed
return {
"total": total,
"completed": completed,
"pending": pending,
"completion_rate": completed / total * 100 if total > 0 else 0
}
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)
步骤4:导出依赖
# 导出依赖
uv pip freeze > requirements.txt
# 查看内容
type requirements.txt # Windows
cat requirements.txt # macOS/Linux
步骤5:运行应用
# 启动FastAPI服务器
uvicorn main:app --reload
# 输出示例:
# INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
# INFO: Started reloader process [12345] using StatReload
# INFO: Started server process [12346]
# INFO: Waiting for application startup.
# INFO: Application startup complete.
步骤6:测试API
方法1:使用浏览器
访问 http://localhost:8000/docs
可以看到自动生成的API文档
方法2:使用curl
# 获取根路径
curl http://localhost:8000/
# 创建任务
curl -X POST "http://localhost:8000/tasks" \
-H "Content-Type: application/json" \
-d '{"title":"学习uv","description":"掌握uv的使用方法","priority":3}'
# 获取所有任务
curl http://localhost:8000/tasks
# 获取单个任务
curl http://localhost:8000/tasks/1
# 更新任务
curl -X PUT "http://localhost:8000/tasks/1" \
-H "Content-Type: application/json" \
-d '{"completed":true}'
# 删除任务
curl -X DELETE "http://localhost:8000/tasks/1"
# 获取统计
curl http://localhost:8000/stats
方法3:使用Python requests
# 创建文件 test_api.py
import requests
BASE_URL = "http://localhost:8000"
# 创建任务
response = requests.post(f"{BASE_URL}/tasks", json={
"title": "学习uv",
"description": "掌握uv的使用方法",
"priority": 3
})
print("创建任务:", response.json())
# 获取所有任务
response = requests.get(f"{BASE_URL}/tasks")
print("所有任务:", response.json())
# 获取统计
response = requests.get(f"{BASE_URL}/stats")
print("统计信息:", response.json())
步骤7:在其他机器上复现
# 克隆项目
cd fastapi_project
# 创建环境
uv venv --python 3.11
.venv\Scripts\activate # Windows
# source .venv/bin/activate # macOS/Linux
# 安装依赖(uv会很快!)
uv pip install -r requirements.txt
# 运行
uvicorn main:app --reload
📁 最终项目结构
fastapi_project/
├── .venv/ # 虚拟环境
├── main.py # FastAPI应用
├── requirements.txt # 依赖列表
└── .gitignore # Git忽略文件
💡 案例总结
通过这个案例,你学会了:
- ✅ 使用uv创建虚拟环境
- ✅ 快速安装FastAPI相关依赖
- ✅ 创建完整的FastAPI应用
- ✅ 运行和测试API
- ✅ 体验uv的极速安装
3.5 实战案例2:机器学习项目
📋 案例背景
使用uv创建一个机器学习项目,需要安装大量依赖:
- numpy, pandas:数据处理
- scikit-learn:机器学习
- matplotlib, seaborn:可视化
- jupyter:交互式开发
🎯 学习目标
通过这个案例,你将学会:
- 批量安装ML库
- 创建ML模型
- 训练和评估模型
- 使用Jupyter Notebook
📝 完整操作步骤
步骤1:创建项目
mkdir ml_project
cd ml_project
# 使用uv创建虚拟环境
uv venv --python 3.10
.venv\Scripts\activate # Windows
# source .venv/bin/activate # macOS/Linux
步骤2:批量安装ML库
# 安装机器学习核心库
uv pip install numpy pandas scikit-learn matplotlib seaborn
# 安装Jupyter
uv pip install jupyter ipywidgets
# 查看安装结果
uv pip list
安装速度:
使用pip:可能需要2-5分钟
使用uv:只需要20-30秒!
步骤3:创建ML脚本
创建文件 ml_demo.py:
# ml_demo.py
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import mean_squared_error, r2_score, mean_absolute_error
import matplotlib.pyplot as plt
import seaborn as sns
# 设置随机种子
np.random.seed(42)
def generate_data(n_samples=1000):
"""生成模拟数据"""
print("生成模拟数据...")
# 生成特征
X = np.random.rand(n_samples, 5) * 10
# 生成目标值(线性关系 + 噪声)
y = (
2 * X[:, 0] +
1.5 * X[:, 1] -
0.5 * X[:, 2] +
3 * X[:, 3] +
X[:, 4] +
np.random.randn(n_samples) * 2
)
return X, y
def train_models(X_train, y_train):
"""训练多个模型"""
print("\n训练模型...")
models = {}
# 线性回归
print("训练线性回归...")
lr = LinearRegression()
lr.fit(X_train, y_train)
models['Linear Regression'] = lr
# 随机森林
print("训练随机森林...")
rf = RandomForestRegressor(n_estimators=100, random_state=42)
rf.fit(X_train, y_train)
models['Random Forest'] = rf
return models
def evaluate_models(models, X_test, y_test):
"""评估模型"""
print("\n评估模型...")
print("=" * 60)
results = []
for name, model in models.items():
# 预测
y_pred = model.predict(X_test)
# 计算指标
mse = mean_squared_error(y_test, y_pred)
mae = mean_absolute_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)
results.append({
'Model': name,
'MSE': mse,
'MAE': mae,
'R²': r2
})
print(f"\n{name}:")
print(f" 均方误差 (MSE): {mse:.4f}")
print(f" 平均绝对误差 (MAE): {mae:.4f}")
print(f" R²分数: {r2:.4f}")
return pd.DataFrame(results)
def plot_predictions(y_test, y_pred, model_name):
"""绘制预测结果"""
plt.figure(figsize=(10, 6))
plt.scatter(y_test, y_pred, alpha=0.5)
plt.plot([y_test.min(), y_test.max()], [y_test.min(), y_test.max()], 'r--', lw=2)
plt.xlabel('实际值')
plt.ylabel('预测值')
plt.title(f'{model_name}: 预测 vs 实际')
plt.grid(True, alpha=0.3)
plt.tight_layout()
filename = f'{model_name.replace(" ", "_")}_predictions.png'
plt.savefig(filename, dpi=300)
print(f"图表已保存: {filename}")
def plot_feature_importance(model, feature_names, model_name):
"""绘制特征重要性"""
if hasattr(model, 'feature_importances_'):
importances = model.feature_importances_
plt.figure(figsize=(10, 6))
indices = np.argsort(importances)[::-1]
plt.bar(range(len(importances)), importances[indices])
plt.xticks(range(len(importances)), [feature_names[i] for i in indices], rotation=45)
plt.xlabel('特征')
plt.ylabel('重要性')
plt.title(f'{model_name}: 特征重要性')
plt.tight_layout()
filename = f'{model_name.replace(" ", "_")}_feature_importance.png'
plt.savefig(filename, dpi=300)
print(f"图表已保存: {filename}")
def main():
"""主函数"""
print("=" * 60)
print("机器学习项目演示")
print("=" * 60)
# 生成数据
X, y = generate_data(n_samples=1000)
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
print(f"\n数据集大小:")
print(f" 训练集: {X_train.shape[0]} 样本")
print(f" 测试集: {X_test.shape[0]} 样本")
print(f" 特征数: {X_train.shape[1]}")
# 训练模型
models = train_models(X_train, y_train)
# 评估模型
results_df = evaluate_models(models, X_test, y_test)
# 绘制预测结果
feature_names = ['Feature 1', 'Feature 2', 'Feature 3', 'Feature 4', 'Feature 5']
for name, model in models.items():
y_pred = model.predict(X_test)
plot_predictions(y_test, y_pred, name)
plot_feature_importance(model, feature_names, name)
print("\n" + "=" * 60)
print("分析完成!")
print("=" * 60)
if __name__ == '__main__':
main()
步骤4:运行ML模型
# 运行ML模型
python ml_demo.py
# 输出示例:
# ============================================================
# 机器学习项目演示
# ============================================================
# 生成模拟数据...
#
# 训练集: 800 样本
# 测试集: 200 样本
# 特征数: 5
#
# 训练模型...
# 训练线性回归...
# 训练随机森林...
#
# 评估模型...
# ============================================================
#
# Linear Regression:
# 均方误差 (MSE): 3.8472
# 平均绝对误差 (MAE): 1.6234
# R²分数: 0.9234
#
# Random Forest:
# 均方误差 (MSE): 4.1234
# 平均绝对误差 (MAE): 1.7123
# R²分数: 0.9156
#
# 图表已保存: Linear_Regression_predictions.png
# 图表已保存: Linear_Regression_feature_importance.png
# 图表已保存: Random_Forest_predictions.png
# 图表已保存: Random_Forest_feature_importance.png
#
# ============================================================
# 分析完成!
# ============================================================
步骤5:使用Jupyter Notebook
# 启动Jupyter
jupyter notebook
# 浏览器会自动打开
在Jupyter中创建notebook:
# 在Jupyter notebook中
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
# 生成数据
X = np.random.rand(100, 1) * 10
y = 2 * X + 1 + np.random.randn(100, 1) * 0.5
# 训练模型
model = LinearRegression()
model.fit(X, y)
# 预测
y_pred = model.predict(X)
# 绘图
plt.scatter(X, y, label='实际值')
plt.plot(X, y_pred, 'r-', label='预测值')
plt.legend()
plt.show()
# 显示结果
print(f"斜率: {model.coef_[0][0]:.2f}")
print(f"截距: {model.intercept_[0]:.2f}")
步骤6:导出依赖
# 导出依赖
uv pip freeze > requirements.txt
# 查看内容
type requirements.txt # Windows
cat requirements.txt # macOS/Linux
📁 最终项目结构
ml_project/
├── .venv/ # 虚拟环境
├── ml_demo.py # ML脚本
├── Linear_Regression_predictions.png
├── Linear_Regression_feature_importance.png
├── Random_Forest_predictions.png
├── Random_Forest_feature_importance.png
├── requirements.txt # 依赖列表
└── .gitignore # Git忽略文件
💡 案例总结
通过这个案例,你学会了:
- ✅ 使用uv批量安装ML库
- ✅ 创建机器学习模型
- ✅ 训练和评估多个模型
- ✅ 可视化结果
- ✅ 使用Jupyter Notebook
3.6 uv常用命令速查表
📋 安装和配置
| 命令 | 说明 |
|---|---|
powershell -c "irm https://astral.sh/uv/install.ps1 | iex" |
Windows安装 |
curl -LsSf https://astral.sh/uv/install.sh | sh |
macOS/Linux安装 |
uv --version |
查看版本 |
uv --help |
查看帮助 |
📦 创建虚拟环境
| 命令 | 说明 |
|---|---|
uv venv |
创建虚拟环境 |
uv venv --python 3.11 |
指定Python版本 |
uv venv --seed |
预装常用包 |
📦 包管理
| 命令 | 说明 |
|---|---|
uv pip install package |
安装包 |
uv pip install package==1.0.0 |
安装指定版本 |
uv pip install -r requirements.txt |
批量安装 |
uv pip install git+https://... |
从Git安装 |
uv pip uninstall package |
卸载包 |
uv pip list |
列出包 |
uv pip show package |
显示包信息 |
uv pip list --outdated |
列出过期包 |
uv pip install --upgrade package |
升级包 |
📝 依赖管理
| 命令 | 说明 |
|---|---|
uv pip freeze > requirements.txt |
导出依赖 |
uv pip resolve package1 package2 |
解析依赖 |
uv pip tree |
显示依赖树 |
💾 缓存管理
| 命令 | 说明 |
|---|---|
uv cache dir |
查看缓存目录 |
uv cache clean |
清理缓存 |
⚙️ 配置
| 命令 | 说明 |
|---|---|
uv pip config set global.index-url URL |
设置镜像源 |
uv pip config list |
查看配置 |
第四章:conda完全教程(数据科学首选)
4.1 工具介绍
📖 什么是conda?
conda是Anaconda发行版的核心包管理器,由Anaconda公司开发,可以管理Python包和非Python依赖。
✅ 优点
- 跨语言支持:可以管理Python、R、C++等包
- 数据科学库完善:预装常用科学计算库
- 系统级依赖管理:可以管理非Python依赖
- 环境管理强大:创建、克隆、删除环境
- 跨平台支持:Windows、macOS、Linux
❌ 缺点
- 体积较大:Anaconda完整版约3GB
- 相对较慢:比pip和uv慢
- 主要面向数据科学:其他场景可能不适用
🎯 适用场景
- ✅ 数据科学和机器学习项目
- ✅ 需要跨语言依赖的项目
- ✅ 需要管理系统级依赖的项目
- ✅ 团队协作的数据分析项目
4.2 安装与准备
步骤1:安装Miniconda
Windows安装
- 访问 https://docs.conda.io/en/latest/miniconda.html
- 下载 Windows installer (64-bit)
- 运行安装程序
- 按提示完成安装(建议勾选"Add Miniconda to PATH")
macOS/Linux安装
# 下载安装脚本
curl -O https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
# 运行安装
bash Miniconda3-latest-Linux-x86_64.sh
# 按提示完成安装
# 最后选择初始化conda(推荐yes)
步骤2:验证安装
# 检查conda版本
conda --version
# 输出示例:
# conda 23.11.0
# 查看conda信息
conda info
步骤3:配置conda(可选)
添加国内镜像源(加速下载)
# 添加清华镜像源
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge
# 设置搜索时显示频道地址
conda config --set show_channel_urls yes
# 查看配置
conda config --show
其他配置
# 设置自动激活base环境
conda config --set auto_activate_base false
# 设置环境更新时询问
conda config --set changeps1 true
4.3 基础操作教程
4.3.1 创建环境
📝 语法说明
conda create --name <环境名> [选项]
💡 实际操作
操作1:创建基础环境
# 创建名为myenv的环境
conda create --name myenv
# 会提示确认:
# Proceed ([y]/n)? y
操作2:创建指定Python版本的环境
# 创建Python 3.10的环境
conda create --name py310 python=3.10
# 创建Python 3.9的环境
conda create --name py39 python=3.9
操作3:创建环境并安装包
# 创建环境并安装包
conda create --name datascience python=3.10 pandas numpy matplotlib
# 创建数据科学环境
conda create --name datascience python=3.10 pandas numpy matplotlib seaborn scikit-learn jupyter
操作4:克隆环境
# 克隆现有环境
conda create --name myenv_clone --clone myenv
📁 环境位置
Windows:
C:\Users\用户名\miniconda3\envs\环境名
macOS/Linux:
~/miniconda3/envs/环境名
4.3.2 激活和退出环境
激活环境
# 激活环境
conda activate myenv
# 激活后,命令行前会出现环境名
(myenv) C:\Users\user>
# ^^^^^
# 环境名
退出环境
# 退出当前环境
conda deactivate
# 退出后,回到base环境或系统环境
(base) C:\Users\user>
查看环境
# 列出所有环境
conda env list
# 或
conda info --envs
# 输出示例:
# # conda environments:
# #
# base * C:\Users\user\miniconda3
# myenv C:\Users\user\miniconda3\envs\myenv
# datascience C:\Users\user\miniconda3\envs\datascience
# ^
# * 表示当前激活的环境
4.3.3 管理包
使用conda安装(推荐)
操作1:安装包
# 安装包
conda install requests
# 安装指定版本
conda install requests=2.28.0
# 安装多个包
conda install pandas numpy matplotlib
操作2:从特定频道安装
# 从conda-forge频道安装
conda install -c conda-forge package_name
# 从多个频道搜索
conda search package_name
操作3:更新包
# 更新包
conda update requests
# 更新所有包
conda update --all
操作4:卸载包
# 卸载包
conda remove requests
操作5:查看包信息
# 列出已安装的包
conda list
# 搜索包
conda search pandas
# 显示包信息
conda show pandas
使用pip安装(conda环境中可用)
# 激活环境后使用pip
conda activate myenv
pip install some_package
# 查看已安装的包
pip list
⚠️ 注意事项
不要混用conda和pip安装同一个包
# ❌ 不推荐
conda install numpy
pip install numpy # 可能导致冲突
# ✅ 推荐
conda install numpy
# 或
pip install numpy
4.3.4 导出和复现环境
导出环境配置
# 导出环境配置
conda env export > environment.yml
# 查看environment.yml内容
cat environment.yml
environment.yml示例:
name: myenv
channels:
- defaults
- conda-forge
dependencies:
- python=3.10
- pandas=1.5.3
- numpy=1.23.5
- matplotlib=3.7.1
- pip:
- requests==2.28.0
从配置文件创建环境
# 从environment.yml创建环境
conda env create -f environment.yml
# 指定环境名
conda env create -f environment.yml --name newenv
更新环境
# 更新现有环境
conda env update -f environment.yml
# 更新并删除不存在的包
conda env update -f environment.yml --prune
4.3.5 管理环境
列出环境
# 列出所有环境
conda env list
# 或
conda info --envs
删除环境
# 删除指定环境
conda remove --name myenv --all
# 删除当前环境
conda remove --name $CONDA_DEFAULT_ENV --all
重命名环境
# conda没有直接重命名命令,通过克隆+删除实现
conda create --name newname --clone oldname
conda remove --name oldname --all
清理环境
# 清理未使用的包
conda clean --packages
# 清理缓存
conda clean --all
# 清理tarball
conda clean --tarballs
4.4 实战案例1:数据科学分析项目
📋 案例背景
使用conda创建一个完整的数据科学分析环境,包含:
- pandas, numpy:数据处理
- matplotlib, seaborn:可视化
- scikit-learn:机器学习
- jupyter:交互式开发
🎯 学习目标
通过这个案例,你将学会:
- 使用conda创建数据科学环境
- 安装数据科学相关库
- 创建数据分析脚本
- 使用Jupyter Notebook
📝 完整操作步骤
步骤1:创建数据科学环境
# 创建环境并安装核心库
conda create --name datascience python=3.10 pandas numpy matplotlib seaborn scikit-learn jupyter
# 激活环境
conda activate datascience
步骤2:安装额外库
# 安装数据处理库
conda install openpyxl xlrd
# 安装可视化库
conda install plotly
# 使用pip安装conda没有的包
pip install yfinance
步骤3:创建分析脚本
创建文件 stock_analysis.py:
# stock_analysis.py
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import yfinance as yf
from datetime import datetime, timedelta
# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei'] # Windows
# plt.rcParams['font.sans-serif'] = ['Arial Unicode MS'] # macOS
plt.rcParams['axes.unicode_minus'] = False
# 设置seaborn样式
sns.set_style("whitegrid")
def get_stock_data(symbol, period='1y'):
"""获取股票数据"""
print(f"正在获取 {symbol} 的数据...")
try:
# 计算日期范围
end_date = datetime.now()
start_date = end_date - timedelta(days=365)
# 获取数据
stock = yf.download(symbol, start=start_date, end=end_date, progress=False)
if stock.empty:
print(f"无法获取 {symbol} 的数据")
return None
print(f"成功获取 {len(stock)} 天的数据")
return stock
except Exception as e:
print(f"获取数据失败: {e}")
return None
def calculate_indicators(stock):
"""计算技术指标"""
# 计算移动平均线
stock['MA20'] = stock['Close'].rolling(window=20).mean()
stock['MA50'] = stock['Close'].rolling(window=50).mean()
# 计算收益率
stock['Returns'] = stock['Close'].pct_change()
# 计算波动率(20日)
stock['Volatility'] = stock['Returns'].rolling(window=20).std()
return stock
def analyze_stock(stock, symbol):
"""分析股票数据"""
print("\n" + "=" * 60)
print(f"{symbol} 股票分析报告")
print("=" * 60)
# 基本信息
print(f"\n【基本信息】")
print(f"数据期间: {stock.index[0].date()} 至 {stock.index[-1].date()}")
print(f"数据天数: {len(stock)} 天")
# 价格统计
print(f"\n【价格统计】")
print(f"最新价格: {stock['Close'].iloc[-1]:.2f}")
print(f"最高价: {stock['High'].max():.2f}")
print(f"最低价: {stock['Low'].min():.2f}")
print(f"平均价: {stock['Close'].mean():.2f}")
# 收益率统计
returns = stock['Returns'].dropna()
print(f"\n【收益率统计】")
print(f"平均日收益率: {returns.mean():.4f}")
print(f"收益率标准差: {returns.std():.4f}")
print(f"累计收益率: {(stock['Close'].iloc[-1] / stock['Close'].iloc[0] - 1) * 100:.2f}%")
# 交易量统计
print(f"\n【交易量统计】")
print(f"平均交易量: {stock['Volume'].mean():.0f}")
print(f"最大交易量: {stock['Volume'].max():.0f}")
# 最新技术指标
print(f"\n【最新技术指标】")
print(f"20日均线: {stock['MA20'].iloc[-1]:.2f}")
print(f"50日均线: {stock['MA50'].iloc[-1]:.2f}")
print(f"20日波动率: {stock['Volatility'].iloc[-1]:.4f}")
def plot_stock_data(stock, symbol):
"""绘制股票数据"""
fig, axes = plt.subplots(3, 2, figsize=(16, 12))
# 图1:价格和移动平均线
axes[0, 0].plot(stock.index, stock['Close'], label='收盘价', linewidth=2)
axes[0, 0].plot(stock.index, stock['MA20'], label='20日均线', alpha=0.7)
axes[0, 0].plot(stock.index, stock['MA50'], label='50日均线', alpha=0.7)
axes[0, 0].set_title(f'{symbol} 股价走势', fontsize=14, fontweight='bold')
axes[0, 0].set_xlabel('日期')
axes[0, 0].set_ylabel('价格')
axes[0, 0].legend()
axes[0, 0].grid(True, alpha=0.3)
# 图2:收益率
axes[0, 1].plot(stock.index, stock['Returns'], alpha=0.7)
axes[0, 1].axhline(y=0, color='r', linestyle='--', alpha=0.5)
axes[0, 1].set_title('日收益率', fontsize=14, fontweight='bold')
axes[0, 1].set_xlabel('日期')
axes[0, 1].set_ylabel('收益率')
axes[0, 1].grid(True, alpha=0.3)
# 图3:交易量
axes[1, 0].bar(stock.index, stock['Volume'], alpha=0.7)
axes[1, 0].set_title('交易量', fontsize=14, fontweight='bold')
axes[1, 0].set_xlabel('日期')
axes[1, 0].set_ylabel('交易量')
axes[1, 0].grid(True, alpha=0.3, axis='y')
# 图4:波动率
axes[1, 1].plot(stock.index, stock['Volatility'], color='orange', linewidth=2)
axes[1, 1].set_title('20日波动率', fontsize=14, fontweight='bold')
axes[1, 1].set_xlabel('日期')
axes[1, 1].set_ylabel('波动率')
axes[1, 1].grid(True, alpha=0.3)
# 图5:收益率分布
axes[2, 0].hist(stock['Returns'].dropna(), bins=50, edgecolor='black', alpha=0.7)
axes[2, 0].set_title('收益率分布', fontsize=14, fontweight='bold')
axes[2, 0].set_xlabel('收益率')
axes[2, 0].set_ylabel('频数')
axes[2, 0].grid(True, alpha=0.3, axis='y')
# 图6:累计收益率
cumulative_returns = (1 + stock['Returns']).cumprod()
axes[2, 1].plot(stock.index, cumulative_returns, linewidth=2, color='green')
axes[2, 1].set_title('累计收益率', fontsize=14, fontweight='bold')
axes[2, 1].set_xlabel('日期')
axes[2, 1].set_ylabel('累计收益率')
axes[2, 1].grid(True, alpha=0.3)
plt.tight_layout()
filename = f'{symbol}_analysis.png'
plt.savefig(filename, dpi=300, bbox_inches='tight')
print(f"\n图表已保存: {filename}")
def main():
"""主函数"""
# 分析苹果股票
symbol = 'AAPL'
# 获取数据
stock = get_stock_data(symbol)
if stock is None:
return
# 计算指标
stock = calculate_indicators(stock)
# 分析
analyze_stock(stock, symbol)
# 绘图
plot_stock_data(stock, symbol)
print("\n分析完成!")
if __name__ == '__main__':
main()
步骤4:运行分析
# 运行分析
python stock_analysis.py
# 输出示例:
# 正在获取 AAPL 的数据...
# 成功获取 252 天的数据
#
# ============================================================
# AAPL 股票分析报告
# ============================================================
#
# 【基本信息】
# 数据期间: 2023-02-18 至 2024-02-18
# 数据天数: 252 天
#
# 【价格统计】
# 最新价格: 182.52
# 最高价: 199.62
# 最低价: 124.17
# 平均价: 164.23
#
# 【收益率统计】
# 平均日收益率: 0.0012
# 收益率标准差: 0.0156
# 累计收益率: 45.23%
#
# 【交易量统计】
# 平均交易量: 52345678
# 最大交易量: 123456789
#
# 【最新技术指标】
# 20日均线: 178.34
# 50日均线: 172.56
# 20日波动率: 0.0123
#
# 图表已保存: AAPL_analysis.png
#
# 分析完成!
步骤5:使用Jupyter Notebook
# 启动Jupyter
jupyter notebook
# 浏览器会自动打开
步骤6:导出环境
# 导出环境配置
conda env export > environment.yml
# 查看内容
cat environment.yml
步骤7:在其他机器上复现
# 从environment.yml创建环境
conda env create -f environment.yml
# 激活环境
conda activate datascience
# 运行分析
python stock_analysis.py
📁 最终项目结构
stock_analysis/
├── stock_analysis.py # 分析脚本
├── AAPL_analysis.png # 生成的图表
├── environment.yml # 环境配置
└── .gitignore # Git忽略文件
💡 案例总结
通过这个案例,你学会了:
- ✅ 使用conda创建数据科学环境
- ✅ 安装数据科学相关库
- ✅ 创建股票分析脚本
- ✅ 使用Jupyter Notebook
- ✅ 导出和复现环境
4.5 实战案例2:深度学习项目
📋 案例背景
使用conda创建深度学习环境,安装PyTorch和相关库。
🎯 学习目标
通过这个案例,你将学会:
- 创建深度学习环境
- 安装PyTorch
- 创建神经网络模型
- 训练和评估模型
📝 完整操作步骤
步骤1:创建深度学习环境
# 创建环境
conda create --name deeplearning python=3.9
# 激活环境
conda activate deeplearning
步骤2:安装PyTorch
# 安装PyTorch(CPU版本)
conda install pytorch torchvision torchaudio cpuonly -c pytorch
# 或安装GPU版本(需要CUDA)
# conda install pytorch torchvision torchaudio cudatoolkit=11.8 -c pytorch
# 验证安装
python -c "import torch; print(f'PyTorch版本: {torch.__version__}')"
步骤3:安装其他ML库
# 安装数据处理库
conda install pandas numpy scikit-learn
# 安装可视化库
conda install matplotlib seaborn plotly
# 安装工具库
pip install tqdm tensorboard
步骤4:创建深度学习脚本
创建文件 pytorch_demo.py:
# pytorch_demo.py
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader, TensorDataset
import numpy as np
import matplotlib.pyplot as plt
from tqdm import tqdm
# 设置随机种子
torch.manual_seed(42)
np.random.seed(42)
# 设置设备
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
print(f"使用设备: {device}")
# 生成示例数据
def generate_data(n_samples=1000):
"""生成模拟数据"""
print("生成模拟数据...")
X = torch.randn(n_samples, 10)
y = torch.sum(X[:, :5], dim=1, keepdim=True) + torch.randn(n_samples, 1) * 0.1
return X, y
# 定义神经网络
class SimpleNet(nn.Module):
def __init__(self, input_size=10, hidden_size=20, output_size=1):
super(SimpleNet, self).__init__()
self.fc1 = nn.Linear(input_size, hidden_size)
self.fc2 = nn.Linear(hidden_size, hidden_size)
self.fc3 = nn.Linear(hidden_size, output_size)
self.relu = nn.ReLU()
self.dropout = nn.Dropout(0.1)
def forward(self, x):
x = self.relu(self.fc1(x))
x = self.dropout(x)
x = self.relu(self.fc2(x))
x = self.dropout(x)
x = self.fc3(x)
return x
# 训练函数
def train_model(model, train_loader, criterion, optimizer, epochs=100):
"""训练模型"""
model.train()
losses = []
print("\n开始训练...")
for epoch in tqdm(range(epochs), desc="训练进度"):
epoch_loss = 0
for batch_X, batch_y in train_loader:
# 移动到设备
batch_X = batch_X.to(device)
batch_y = batch_y.to(device)
# 前向传播
outputs = model(batch_X)
loss = criterion(outputs, batch_y)
# 反向传播和优化
optimizer.zero_grad()
loss.backward()
optimizer.step()
epoch_loss += loss.item()
avg_loss = epoch_loss / len(train_loader)
losses.append(avg_loss)
if (epoch + 1) % 10 == 0:
print(f'Epoch [{epoch+1}/{epochs}], Loss: {avg_loss:.6f}')
return losses
# 评估函数
def evaluate_model(model, test_loader, criterion):
"""评估模型"""
model.eval()
total_loss = 0
with torch.no_grad():
for batch_X, batch_y in test_loader:
batch_X = batch_X.to(device)
batch_y = batch_y.to(device)
outputs = model(batch_X)
loss = criterion(outputs, batch_y)
total_loss += loss.item()
return total_loss / len(test_loader)
def main():
"""主函数"""
print("=" * 60)
print("PyTorch深度学习演示")
print("=" * 60)
# 生成数据
X, y = generate_data(n_samples=1000)
# 划分训练集和测试集
train_size = int(0.8 * len(X))
X_train, X_test = X[:train_size], X[train_size:]
y_train, y_test = y[:train_size], y[train_size:]
print(f"\n数据集大小:")
print(f" 训练集: {len(X_train)} 样本")
print(f" 测试集: {len(X_test)} 样本")
print(f" 特征数: {X_train.shape[1]}")
# 创建数据加载器
train_dataset = TensorDataset(X_train, y_train)
test_dataset = TensorDataset(X_test, y_test)
train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=32, shuffle=False)
# 初始化模型
model = SimpleNet(input_size=10, hidden_size=20, output_size=1).to(device)
# 定义损失函数和优化器
criterion = nn.MSELoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)
# 训练模型
losses = train_model(model, train_loader, criterion, optimizer, epochs=100)
# 评估模型
test_loss = evaluate_model(model, test_loader, criterion)
print(f'\n测试集损失: {test_loss:.6f}')
# 绘制损失曲线
plt.figure(figsize=(10, 6))
plt.plot(losses, linewidth=2)
plt.title('训练损失曲线', fontsize=14, fontweight='bold')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.savefig('training_loss.png', dpi=300)
print('损失曲线已保存为 training_loss.png')
# 测试预测
model.eval()
with torch.no_grad():
test_sample = X_test[:5].to(device)
predictions = model(test_sample)
actual = y_test[:5].to(device)
print("\n预测示例:")
for i in range(5):
print(f" 实际值: {actual[i].item():.4f}, 预测值: {predictions[i].item():.4f}")
print("\n" + "=" * 60)
print("训练完成!")
print("=" * 60)
if __name__ == '__main__':
main()
步骤5:运行训练
# 运行训练
python pytorch_demo.py
# 输出示例:
# ============================================================
# PyTorch深度学习演示
# ============================================================
# 使用设备: cuda
# 生成模拟数据...
#
# 数据集大小:
# 训练集: 800 样本
# 测试集: 200 样本
# 特征数: 10
#
# 开始训练...
# 训练进度: 100%|██████████| 100/100 [00:05<00:00, 18.23it/s]
# Epoch [10/100], Loss: 0.012345
# Epoch [20/100], Loss: 0.009876
# ...
# Epoch [100/100], Loss: 0.001234
#
# 测试集损失: 0.001567
# 损失曲线已保存为 training_loss.png
#
# 预测示例:
# 实际值: 1.2345, 预测值: 1.2367
# 实际值: -0.5678, 预测值: -0.5654
# ...
#
# ============================================================
# 训练完成!
# ============================================================
步骤6:导出环境
# 导出环境配置
conda env export > dl_environment.yml
📁 最终项目结构
deeplearning/
├── pytorch_demo.py # 训练脚本
├── training_loss.png # 损失曲线
├── dl_environment.yml # 环境配置
└── .gitignore # Git忽略文件
💡 案例总结
通过这个案例,你学会了:
- ✅ 使用conda创建深度学习环境
- ✅ 安装PyTorch
- ✅ 创建神经网络模型
- ✅ 训练和评估模型
- ✅ 使用GPU加速(如果可用)
4.6 conda常用命令速查表
📋 环境管理
| 命令 | 说明 | |
|---|---|---|
conda create --name myenv |
创建环境 | |
conda create --name py39 python=3.9 |
指定Python版本 | |
conda create --name myenv --clone oldenv |
克隆环境 | |
conda activate myenv |
激活环境 | |
conda deactivate |
退出环境 | |
conda env list |
列出环境 | |
conda remove --name myenv --all |
删除环境 |
📦 包管理
| 命令 | 说明 |
|---|---|
conda install package |
安装包 |
conda install package=1.0.0 |
安装指定版本 |
conda install -c conda-forge package |
从频道安装 |
conda update package |
更新包 |
conda remove package |
卸载包 |
conda list |
列出包 |
conda search package |
搜索包 |
conda show package |
显示包信息 |
📝 环境导出/导入
| 命令 | 说明 |
|---|---|
| `conda env export > environment.yml`` | 导出环境 |
| `conda env create -f environment.yml`` | 从文件创建环境 |
conda env update -f environment.yml |
更新环境 |
⚙️ 配置
| 命令 | 说明 |
|---|---|
conda config --add channels URL |
添加频道 |
conda config --show |
显示配置 |
conda config --remove channels URL |
移除频道 |
🔧 其他
| 命令 | 说明 |
|---|---|
conda update conda |
更新conda |
conda clean --all |
清理缓存 |
conda info |
显示conda信息 |
第五章:pipenv完全教程(依赖管理利器)
5.1 工具介绍
📖 什么是pipenv?
pipenv是Kenneth Reitz(requests作者)开发的官方推荐的Python项目管理工具,结合了pip、virtualenv和requirements.txt的功能。
✅ 优点
- 自动生成Pipfile和Pipfile.lock
- 自动锁定依赖版本
- 自动创建和管理虚拟环境
- 支持开发依赖分离
- 兼容requirements.txt
- 简洁的命令行界面
❌ 缺点
- 依赖解析较慢
- 维护频率降低
- 某些情况下可能出现兼容性问题
- Pipfile.lock文件较大
🎯 适用场景
- ✅ 中小型Python项目
- ✅ 需要明确依赖版本的项目
- ✅ 团队协作项目
- ✅ 需要开发/生产依赖分离的项目
5.2 安装与准备
步骤1:安装pipenv
# 使用pip安装
pip install pipenv
# 或使用pipx安装(推荐)
pip install pipx
pipx install pipenv
`步骤2:验证安装
# 检查版本
pipenv --version
# 输出示例:
# Pipenv version 2023.11.14
# 查看帮助
pipenv --help
步骤3:配置pipenv(可选)
# 设置虚拟环境在项目目录
export PIPENV_VENV_IN_PROJECT=1
# 设置Python版本
export PIPENV_PYTHON=3.10
5.3 基础操作教程
5.3.1 创建项目
📝 操作方法
# 创建项目目录
mkdir myproject
cd myproject
# 初始化项目(自动创建虚拟环境)
pipenv install
# 指定Python版本
pipenv --python 3.10
📁 生成的文件
myproject/
├── Pipfile # 依赖配置文件
└── Pipfile.lock # 锁定的依赖版本
📝 Pipfile示例
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"
[packages]
requests = "*"
[dev-packages]
[requires]
python_version = "3.10"
5.3.2 管理依赖
📦 安装依赖
# 安装依赖(自动添加到Pipfile)
pipenv install requests
# 安装指定版本
pipenv install requests==2.28.0
# 安装多个依赖
pipenv install requests pandas numpy
# 安装开发依赖
pipenv install pytest --dev
# 从requirements.txt安装
pipenv install -r requirements.txt
🔄 更新和卸载
# 卸载依赖
pipenv uninstall requests
# 更新依赖
pipenv update requests
# 更新所有依赖
pipenv update
5.3.3 激活虚拟环境
# 激活虚拟环境
pipenv shell
# 激活后,命令行前会出现项目名
(myproject) $
5.3.4 在虚拟环境中运行命令
# 运行Python脚本
pipenv run python main.py
# 运行测试
pipenv run pytest
# 运行任意命令
pipenv run npm install
# 不激活环境直接运行
pipenv run python script.py
5.3.5 查看依赖信息
# 查看依赖图
pipenv graph
# 输出示例:
# requests==2.28.0
# - certifi [required: >=2017.4.17]
# - charset-normalizer [required: >=2,<3]
# - idna [required: >=2.5,<4]
# - urllib3 [required: >=1.21.1,<1.27]
# 查看已安装的包
pipenv run pip list
# 检查安全漏洞
pipenv check
# 查看虚拟环境路径
pipenv --venv
5.3.6 锁定依赖
# 生成Pipfile.lock
pipenv lock
# 更新Pipfile.lock
pipenv lock --update
5.4 实战案例1:Flask Web应用
📋 案例背景
使用pipenv创建一个Flask Web应用,包含数据库、用户认证等功能。
🎯 学习目标
通过这个案例,你将学会:
- 使用pipenv创建项目
- 管理开发和生产依赖
- 创建Flask应用
- 运行和测试应用
📝 完整操作步骤
步骤1:创建项目
mkdir flask_app
cd flask_app
步骤2:初始化项目
# 指定Python版本并初始化
pipenv --python 3.10
# 安装Flask和依赖
pipenv install flask flask-sqlalchemy flask-login flask-wtf email-validator
步骤3:安装开发依赖
pipenv install pytest pytest-cov black flake8 --dev
步骤4:查看Pipfile
cat Pipfile
# 内容:
# [[source]]
# url = "https://pypi.org/simple"
# verify_ssl = true
# name = "pypi"
#
# [packages]
# flask = "*"
# flask-sqlalchemy = "*"
# flask-login = "*"
# flask-wtf = "*"
# email-validator = "*"
#
# [dev-packages]
# pytest = "*"
# pytest-cov = "*"
# black = "*"
# flake8 = "*"
#
# [requires]
# python_version = "3.10"
步骤5:创建应用代码
创建文件 app.py:
# app.py
from flask import Flask, render_template, request, redirect, url_for, flash
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime
app = Flask(__name__)
app.config['SECRET_KEY'] = 'your-secret-key-here'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///tasks.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
# 数据模型
class Task(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(100), nullable=False)
description = db.Column(db.Text, nullable=True)
priority = db.Column(db.Integer, default=1)
completed = db.Column(db.Boolean, default=False)
created_at = db.Column(db.DateTime, default=datetime.utcnow)
def __repr__(self):
return f'<Task {self.title}>'
# 创建数据库表
with app.app_context():
db.create_all()
# 路由
@app.route('/')
def index():
tasks = Task.query.order_by(Task.created_at.desc()).all()
return render_template('index.html', tasks=tasks)
@app.route('/add', methods=['POST'])
def add():
title = request.form.get('title')
description = request.form.get('description')
priority = request.form.get('priority', 1, type=int)
if title:
task = Task(title=title, description=description, priority=priority)
db.session.add(task)
db.session.commit()
flash('任务已添加!', 'success')
else:
flash('请输入任务标题!', 'error')
return redirect(url_for('index'))
@app.route('/complete/<int:id>')
def complete(id):
task = Task.query.get_or_404(id)
task.completed = not task.completed
db.session.commit()
flash('任务状态已更新!', 'success')
return redirect(url_for('index'))
@app.route('/delete/<int:id>')
def delete(id):
task = Task.query.get_or_404(id)
db.session.delete(task)
db.session.commit()
flash('任务已删除!', 'success')
return redirect(url_for('index'))
@app.route('/edit/<int:id>', methods=['GET', 'POST'])
def edit(id):
task = Task.query.get_or_404(id)
if request.method == 'POST':
task.title = request.form.get('title')
task.description = request.form.get('description')
task.priority = request.form.get('priority', 1, type=int)
db.session.commit()
flash('任务已更新!', 'success')
return redirect(url_for('index'))
return render_template('edit.html', task=task)
if __name__ == '__main__':
app.run(debug=True)
步骤6:创建HTML模板
创建templates目录和文件:
mkdir templates
创建文件 templates/base.html:
<!DOCTYPE html>
<html>
<head>
<title>{% block title %}任务管理{% endblock %}</title>
<style>
body { font-family: Arial, sans-serif; max-width: 900px; margin: 0 auto; padding: 20px; }
.task { padding: 15px; margin: 10px 0; background: #f5f5f5; border-radius: 5px; }
.task.completed { text-decoration: line-through; opacity: 0.6; }
.priority-1 { border-left: 4px solid #4CAF50; }
.priority-2 { border-left: 4px solid #2196F3; }
.priority-3 { border-left: 4px solid #FF9800; }
.priority-4 { border-left: 4px solid #F44336; }
.priority-5 { border-left: 4px solid #9C27B0; }
form { margin: 20px 0; }
input[type="text"], textarea { padding: 8px; width: 300px; }
input[type="submit"] { padding: 8px 16px; background: #2196F3; color: white; border: none; cursor: pointer; }
a { margin-left: 10px; text-decoration: none; color: #2196F3; }
.flash { padding: 10px; margin: 10px 0; border-radius: 5px; }
.flash.success { background: #4CAF50; color: white; }
.flash.error { background: #F44336; color: white; }
</style>
</head>
<body>
<h1>{% block header %}任务管理{% endblock %}</h1>
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
{% for category, message in messages %}
<div class="flash {{ category }}">{{ message }}</div>
{% endfor %}
{% endif %}
{% endwith %}
{% block content %}{% endblock %}
</body>
</html>
创建文件 templates/index.html:
{% extends "base.html" %}
{% block title %}任务列表{% endblock %}
{% block content %}
<form action="/add" method="post">
<input type="text" name="title" placeholder="输入任务标题" required>
<input type="text" name="description" placeholder="任务描述(可选)">
<select name="priority">
<option value="1">低优先级</option>
<option value="2">中优先级</option>
<option value="3" selected>高优先级</option>
<option value="4">紧急</option>
<option value="5">非常紧急</option>
</select>
<input type="submit" value="添加任务">
</form>
{% for task in tasks %}
<div class="task priority-{{ task.priority }} {% if task.completed %}completed{% endif %}">
<h3>{{ task.title }}</h3>
{% if task.description %}
<p>{{ task.description }}</p>
{% endif %}
<p>优先级: {{ task.priority }} | 创建时间: {{ task.created_at.strftime('%Y-%m-%d %H:%M') }}</p>
<a href="/complete/{{ task.id }}">完成</a>
<a href="/edit/{{ task.id }}">编辑</a>
<a href="/delete/{{ task.id }}">删除</a>
</div>
{% endfor %}
{% if not tasks %}
<p>暂无任务,添加一个吧!</p>
{% endif %}
{% endblock %}
创建文件 templates/edit.html:
{% extends "base.html" %}
{% block title %}编辑任务{% endblock %}
{% block content %}
<form action="/edit/{{ task.id }}" method="post">
<input type="text" name="title" value="{{ task.title }}" required>
<textarea name="description">{{ task.description or '' }}</textarea>
<select name="priority">
<option value="1" {% if task.priority == 1 %}selected{% endif %}>低优先级</option>
<option value="2" {% if task.priority == 2 %}selected{% endif %}>中优先级</option>
<option value="3" {% if task.priority == 3 %}selected{% endif %}>高优先级</option>
<option value="4" {% if task.priority == 4 %}selected{% endif %}>紧急</option>
<option value="5" {% if task.priority == 5 %}selected{% endif %}>非常紧急</option>
</select>
<input type="submit" value="更新任务">
</form>
<a href="/">返回列表</a>
{% endblock %}
步骤7:运行应用
# 激活虚拟环境
pipenv shell
# 运行应用
python app.py
# 或直接运行
pipenv run python app.py
访问 http://127.0.0.1:5000 查看应用。
步骤8:创建测试
创建文件 tests/test_app.py:
import pytest
from app import app, db, Task
@pytest.fixture
def client():
app.config['TESTING'] = True
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///:memory:'
with app.app_context():
db.create_all()
yield app.test_client()
db.drop_all()
def test_index(client):
response = client.get('/')
assert response.status_code == 200
assert b'任务管理' in response.data
def test_add_task(client):
response = client.post('/add', data={
'title': '测试任务',
'description': '这是一个测试任务',
'priority': 3
})
assert response.status_code == 302
with app.app_context():
task = Task.query.first()
assert task.title == '测试任务'
assert task.description == '这是一个测试任务'
assert task.priority == 3
def test_complete_task(client):
# 先添加任务
client.post('/add', data={'title': '测试任务', 'priority': 1})
# 完成任务
with app.app_context():
task = Task.query.first()
task_id = task.id
response = client.get(f'/complete/{task_id}')
assert response.status_code == 302
with app.app_context():
task = Task.query.first()
assert task.completed == True
步骤9:运行测试
# 运行测试
pipenv run pytest
# 运行测试并生成覆盖率报告
pipenv run pytest --cov=app --cov-report=html
步骤10:代码格式化
# 格式化代码
pipenv run black .
# 检查代码风格
pipenv run flake8
📁 最终项目结构
flask_app/
├── Pipfile # 依赖配置
├── Pipfile.lock # 锁定的依赖
├── app.py # Flask应用
├── templates/ # HTML模板
│ ├── base.html
│ ├── index.html
│ └── edit.html
├── tests/ # 测试
│ └── test_app.py
├── tasks.db # SQLite数据库
└── .gitignore # Git忽略文件
💡 案例总结
通过这个案例,你学会了:
- ✅ 使用pipenv创建项目
- ✅ 管理开发和生产依赖
- ✅ 创建完整的Flask应用
- ✅ 编写和运行测试
- ✅ 代码格式化和检查
5.5 实战案例2:API客户端项目
📋 案例背景
创建一个API客户端项目,需要管理多个API的依赖。
🎯 学习目标
通过这个案例,你将学会:
- 使用pipenv管理API依赖
- 创建同步和异步API客户端
- 处理API响应
- 错误处理
📝 完整操作步骤
步骤1:创建项目
mkdir api_client
cd api_client
步骤2:初始化项目
pipenv --python 3.9
pipenv install requests httpx aiohttp pydantic python-dotenv
步骤3:创建配置文件
# 创建 .env 文件
echo "API_BASE_URL=https://api.example.com" > .env
echo "API_KEY=your-api-key-here" >> .env
echo "TIMEOUT=30" >> .env
步骤4:创建API客户端
创建文件 api_client.py:
# api_client.py
import os
from typing import Optional, Dict, Any, List
import requests
import httpx
from dotenv import load_dotenv
from pydantic import BaseModel, Field
load_dotenv()
class APIResponse(BaseModel):
"""API响应模型"""
status: str
data: Optional[Dict[str, Any]] = None
message: Optional[str] = None
class APIClient:
"""通用API客户端"""
def __init__(
self,
base_url: str,
api_key: Optional[str] = None,
timeout: int = 30
):
self.base_url = base_url.rstrip('/')
self.api_key = api_key
self.timeout = timeout
self.session = requests.Session()
if api_key:
self.session.headers.update({
'Authorization': f'Bearer {api_key}',
'Content-Type': 'application/json'
})
def get(self, endpoint: str, params: Optional[Dict] = None) -> Dict[str, Any]:
"""GET请求"""
url = f'{self.base_url}/{endpoint.lstrip("/")}'
try:
response = self.session.get(url, params=params, timeout=self.timeout)
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException as e:
return {'error': str(e)}
def post(self, endpoint: str, data: Optional[Dict] = None) -> Dict[str, Any]:
"""POST请求"""
url = f'{self.base_url}/{endpoint.lstrip("/")}'
try:
response = self.session.post(url, json=data, timeout=self.timeout)
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException as e:
return {'error': str(e)}
def put(self, endpoint: str, data: Optional[Dict] = None) -> Dict[str, Any]:
"""PUT请求"""
url = f'{self.base_url}/{endpoint.lstrip("/")}'
try:
response = self.session.put(url, json=data, timeout=self.timeout)
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException as e:
return {'error': str(e)}
def delete(self, endpoint: str) -> Dict[str, Any]:
"""DELETE请求"""
url = f'{self.base_url}/{endpoint.lstrip("/")}'
try:
response = self.session.delete(url, timeout=self.timeout)
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException as e:
return {'error': str(e)}
# 创建客户端实例
client = APIClient(
base_url=os.getenv('API_BASE_URL', 'https://jsonplaceholder.typicode.com'),
api_key=os.getenv('API_KEY'),
timeout=int(os.getenv('TIMEOUT', 30))
)
def test_api():
"""测试API"""
print("=" * 60)
print("API客户端测试")
print("=" * 60)
# 测试GET请求
print("\n1. 测试GET请求...")
users = client.get('/users')
if 'error' not in users:
print(f"成功获取 {len(users)} 个用户")
print(f"第一个用户: {users[0]['name']}")
else:
print(f"错误: {users['error']}")
# 测试POST请求
print("\n2. 测试POST请求...")
new_post = client.post('/posts', data={
'title': '测试文章',
'body': '这是一篇测试文章',
'userId': 1
})
if 'error' not in new_post:
print(f"成功创建文章,ID: {new_post['id']}")
else:
print(f"错误: {new_post['error']}")
# 测试GET单个资源
print("\n3. 测试GET单个资源...")
post = client.get('/posts/1')
if 'error' not in post:
print(f"文章标题: {post['title']}")
else:
print(f"错误: {post['error']}")
print("\n测试完成!")
if __name__ == '__main__':
test_api()
步骤5:运行测试
pipenv run python api_client.py
# 输出示例:
# ============================================================
# API客户端测试
# ============================================================
#
# 1. 测试GET请求...
# 成功获取 10 个用户
# 第一个用户: Leanne Graham
#
# 2. 测试POST请求...
# 成功创建文章,ID: 101
#
# 3. 测试GET单个资源...
# 文章标题: sunt aut facere repellat provident occaecati excepturi optio reprehenderit
#
# 测试完成!
步骤6:创建异步客户端
创建文件 async_client.py:
# async_client.py
import asyncio
import aiohttp
from typing import Optional, Dict, Any, List
from pydantic import BaseModel
class AsyncAPIClient:
"""异步API客户端"""
def __init__(
self,
base_url: str,
api_key: Optional[str] = None,
timeout: int = 30
):
self.base_url = base_url.rstrip('/')
self.api_key = api_key
self.timeout = timeout
async def get(self, endpoint: str, params: Optional[Dict] = None) -> Dict[str, Any]:
"""异步GET请求"""
url = f'{self.base_url}/{endpoint.lstrip("/")}'
headers = {}
if self.api_key:
headers['Authorization'] = f'Bearer {self.api_key}'
try:
async with aiohttp.ClientSession() as session:
async with session.get(url, params=params, headers=headers, timeout=self.timeout) as response:
response.raise_for_status()
return await response.json()
except Exception as e:
return {'error': str(e)}
async def get_multiple(self, endpoints: List[str]) -> List[Dict[str, Any]]:
"""并发获取多个资源"""
tasks = [self.get(endpoint) for endpoint in endpoints]
return await asyncio.gather(*tasks)
async def test_async_api():
"""测试异步API"""
print("=" * 60)
print("异步API客户端测试")
print("=" * 60)
client = AsyncAPIClient('https://jsonplaceholder.typicode.com')
# 测试并发请求
print("\n并发获取多个用户...")
endpoints = [f'/users/{i}' for i in range(1, 6)]
users = await client.get_multiple(endpoints)
for user in users:
if 'error' not in user:
print(f"{user['name']}: {user['email']}")
else:
print(f"错误: {user['error']}")
print("\n测试完成!")
if __name__ == '__main__':
asyncio.run(test_async_api())
步骤7:运行异步客户端
pipenv run python async_client.py
# 输出示例:
# ============================================================
# 异步API客户端测试
# ============================================================
#
# 并发获取多个用户...
# Leanne Graham: Sincere@april.biz
# Ervin Howell: Shanna@melissa.tv
# Clementine Bauch: Nathan@yesenia.net
# Patricia Lebsack: Julianne.OConner@kory.org
# Chelsey Dietrich: Lucio_Hettinger@annie.ca
#
# 测试完成!
📁 最终项目结构
api_client/
├── Pipfile # 依赖配置
├── Pipfile.lock # 锁定的依赖
├── api_client.py # 同步API客户端
├── async_client.py # 异步API客户端
├── .env # 环境变量
└── .gitignore # Git忽略文件
💡 案例总结
通过这个案例,你学会了:
- ✅ 使用pipenv管理API依赖
- ✅ 创建同步API客户端
- ✅ 创建异步API客户端
- ✅ 处理API响应和错误
- ✅ 使用环境变量
5.6 pipenv常用命令速查表
📋 安装和初始化
| 命令 | 说明 |
|---|---|
pip install pipenv |
使用pip安装 |
pipx install pipenv |
使用pipx安装(推荐) |
pipenv install |
初始化项目 |
pipenv --python 3.10 |
指定Python版本 |
📦 依赖管理
| 命令 | 说明 |
|---|---|
pipenv install package |
安装依赖 |
pipenv install package==1.0.0 |
安装指定版本 |
pipenv install -r requirements.txt |
从requirements.txt安装 |
pipenv install pytest --dev |
安装开发依赖 |
pipenv uninstall package |
卸载依赖 |
pipenv update package |
更新依赖 |
pipenv update |
更新所有依赖 |
🔄 虚拟环境
| 命令 | 说明 |
|---|---|
pipenv shell |
激活虚拟环境 |
pipenv --venv |
查看虚拟环境路径 |
pipenv --rm |
删除虚拟环境 |
🏃 运行命令
| 命令 | 说明 |
|---|---|
pipenv run python script.py |
运行Python脚本 |
pipenv run pytest |
运行测试 |
pipenv run black . |
格式化代码 |
📊 依赖信息
| 命令 | 说明 |
|---|---|
pipenv graph |
查看依赖图 |
pipenv lock |
生成Pipfile.lock |
pipenv check |
检查安全漏洞 |
第六章:poetry完全教程(现代化项目管理)
6.1 工具介绍
📖 什么是poetry?
poetry是现代化的Python依赖管理和打包工具,提供完整的项目生命周期管理。
✅ 优点
- 优雅的命令行界面
- 完整的项目管理(依赖、构建、发布)
- 强大的依赖解析
- 使用pyproject.toml作为配置文件
- 支持虚拟环境自动管理
- 支持依赖组和可选依赖
❌ 缺点
- 学习曲线稍陡
- 某些高级功能需要熟悉
- poetry.lock文件较大
🎯 适用场景
- ✅ 专业Python项目
- ✅ 需要发布到PyPI的项目
- ✅ 复杂依赖管理项目
- ✅ 团队协作的企业级项目
6.2 安装与准备
步骤1:安装poetry
官方安装脚本(推荐):
curl -sSL https://install.python-poetry.org | python3 -
使用pip安装:
pip install poetry
使用pipx安装(推荐):
pip install pipx
pipx install poetry
步骤2:验证安装
# 检查版本
poetry --version
# 输出示例:
# Poetry version 1.7.1
# 查看帮助
poetry --help
步骤3:配置poetry(可选)
# 配置虚拟环境在项目目录
poetry config virtualenvs.in-project true
# 配置镜像源
poetry config repositories.tsinghua https://pypi.tuna.tsinghua.edu.cn/simple
# 查看配置
poetry config --list
6.3 基础操作教程
6.3.1 创建新项目
📝 操作方法
# 创建新项目
poetry new myproject
# 生成的目录结构:
# myproject/
# ├── pyproject.toml # 项目配置文件
# ├── README.md
# ├── myproject/
# │ └── __init__.py
# └── tests/
# └── __init__.py
在现有目录初始化
cd existing_project
poetry init
6.3.2 管理依赖
📦 添加依赖
# 添加依赖
poetry add requests
# 添加指定版本
poetry add requests@^2.28.0
# 添加多个依赖
poetry add requests pandas numpy
# 添加开发依赖
poetry add --group dev pytest black
# 添加可选依赖
poetry add --optional excel openpyxl
# 移除依赖
poetry remove requests
# 更新依赖
poetry update
# 更新特定依赖
poetry update requests
6.3.3 安装依赖
# 安装项目依赖
poetry install
# 只安装主依赖
poetry install --only main
# 安装开发依赖
poetry install --with dev
# 安装可选依赖组
poetry install --with excel
# 安装所有依赖(包括可选)
poetry install --all-extras
6.3.4 使用虚拟环境
# 激活虚拟环境
poetry shell
# 在虚拟环境中运行命令
poetry run python main.py
poetry run pytest
# 查看虚拟环境信息
poetry env info
# 查看虚拟环境路径
poetry env list
# 删除虚拟环境
poetry env remove python3.10
6.3.5 构建和发布
# 构建项目
poetry build
# 发布到PyPI
poetry publish
# 发布到测试PyPI
poetry publish --repository testpypi
# 检查项目配置
poetry check
6.4 实战案例1:命令行工具项目
📋 案例背景
使用poetry创建一个命令行工具项目,包含CLI界面、配置管理等功能。
🎯 学习目标
通过这个案例,你将学会:
- 使用poetry创建CLI项目
- 使用Click和Rich创建美观的CLI
- 管理依赖组
- 构建和发布工具
📝 完整操作步骤
步骤1:创建项目
poetry new cli_tool
cd cli_tool
步骤2:查看pyproject.toml
cat pyproject.toml
# 内容:
# [tool.poetry]
# name = "cli-tool"
# version = "0.1.0"
# description = ""
# authors = ["Your Name <you@example.com>"]
# readme = "README.md"
# packages = [{include = "cli_tool"}]
#
# [tool.poetry.dependencies]
# python = "^3.9"
#
# [tool.poetry.group.dev.dependencies]
# pytest = "^7.4.0"
#
# [build-system]
# requires = ["poetry-core"]
# build-backend = "poetry.core.masonry.api"
步骤3:添加依赖
poetry add click rich typer python-dotenv
poetry add --group dev pytest pytest-cov black mypy
步骤4:创建CLI工具
修改文件 cli_tool/__init__.py:
# cli_tool/__init__.py
import click
from rich.console import Console
from rich.table import Table
from rich.progress import track
import time
console = Console()
@click.group()
@click.version_option(version='0.1.0')
def cli():
"""命令行工具 - 一个现代化的CLI工具"""
pass
@cli.command()
@click.option('--name', default='World', help='要问候的名字')
@click.option('--count', default=1, help='问候次数')
def hello(name, count):
"""问候命令"""
更多推荐



所有评论(0)