Python虚拟环境终极指南:新手从零到精通(含实战案例)

前言:你是否遇到过这些困扰?

  • 项目A需要Django 3.2,项目B需要Django 4.0,安装后互相冲突?
  • 想尝试新库却担心污染系统环境?
  • 换了台电脑,项目环境怎么都配不好?
  • 看到别人用各种虚拟环境工具,不知道该选哪个?

别担心!本文将手把手教你使用venv、、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+版本官方内置的虚拟环境创建模块。

✅ 优点
  1. 无需安装:Python自带,开箱即用
  2. 官方支持:稳定可靠,长期维护
  3. 轻量级:只包含必要文件,占用空间小
  4. 学习成本低:命令简单,容易理解
❌ 缺点
  1. 功能基础:没有高级依赖管理功能
  2. 手动操作:需要手动管理requirements.txt
  3. 无依赖锁定:不会自动锁定依赖版本
🎯 适用场景
  • ✅ 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
💡 激活成功的标志

激活成功后,你会看到:

  1. 命令行前面出现(venv)标识
  2. 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
⚠️ 注意事项
  1. 确保已退出虚拟环境

    # 先退出
    deactivate
    
    # 再删除
    rm -rf venv
    
  2. 删除前确认

    # 查看虚拟环境内容
    ls venv  # macOS/Linux
    dir venv  # Windows
    
    # 确认无误后再删除
    
  3. 不要删除系统Python

    # 只删除项目目录下的venv文件夹
    # 不要删除C:\Python310或/usr/bin/python
    

2.4 实战案例1:Web爬虫项目

📋 案例背景

创建一个简单的网页爬虫项目,需要使用以下库:

  • requests:发送HTTP请求
  • beautifulsoup4:解析HTML
  • lxml:HTML解析器
🎯 学习目标

通过这个案例,你将学会:

  1. 创建和激活虚拟环境
  2. 安装多个依赖包
  3. 编写Python脚本
  4. 导出依赖列表
  5. 在其他机器上复现环境
📝 完整操作步骤
步骤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忽略文件
💡 案例总结

通过这个案例,你学会了:

  1. ✅ 创建项目目录和虚拟环境
  2. ✅ 激活虚拟环境
  3. ✅ 安装多个依赖包
  4. ✅ 编写和运行Python脚本
  5. ✅ 导出依赖列表
  6. ✅ 创建.gitignore文件
  7. ✅ 在其他机器上复现环境

2.5 实战案例2:数据分析项目

📋 案例背景

创建一个数据分析项目,需要使用以下库:

  • pandas:数据处理
  • numpy:数值计算
  • matplotlib:数据可视化
  • seaborn:统计图表
🎯 学习目标

通过这个案例,你将学会:

  1. 安装数据分析相关库
  2. 创建数据分析脚本
  3. 生成图表
  4. 使用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忽略文件
💡 案例总结

通过这个案例,你学会了:

  1. ✅ 安装数据分析相关库
  2. ✅ 创建数据分析脚本
  3. ✅ 使用pandas处理数据
  4. ✅ 使用matplotlib和seaborn绘制图表
  5. ✅ 使用Jupyter Notebook(可选)
  6. ✅ 导出依赖列表

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最佳实践

✅ 推荐做法
  1. 每个项目使用独立的虚拟环境

    cd project-a
    python -m venv venv
    
    cd project-b
    python -m venv venv
    
  2. 使用标准命名

    # 推荐
    python -m venv venv
    python -m venv .venv
    
    # 不推荐
    python -m venv my_virtual_environment_123
    
  3. 及时更新pip

    pip install --upgrade pip
    
  4. 使用requirements.txt

    pip freeze > requirements.txt
    
  5. 创建.gitignore

    venv/
    .venv/
    __pycache__/
    *.pyc
    
  6. 在README中说明环境配置

    ## 环境配置
    
    ```bash
    python -m venv venv
    source venv/bin/activate  # Windows: venv\Scripts\activate
    pip install -r requirements.txt
    
    
    
❌ 避免做法
  1. 不要在系统Python中安装包

    # ❌ 错误
    sudo pip install package
    
    # ✅ 正确
    python -m venv venv
    source venv/bin/activate
    pip install package
    
  2. 不要提交虚拟环境到git

    # .gitignore
    venv/
    .venv/
    
  3. 不要混用不同Python版本

    # ❌ 错误
    python3.9 -m venv venv
    python3.10 -m venv venv  # 覆盖了上面的
    
    # ✅ 正确
    python3.9 -m venv venv39
    python3.10 -m venv venv310
    
  4. 不要在虚拟环境中使用sudo

    # ❌ 错误
    sudo pip install package
    
    # ✅ 正确
    pip install package
    

第三章:uv完全教程(新一代极速工具)

3.1 工具介绍

📖 什么是uv?

uv是由Astral团队(Ruff开发者)开发的极速Python包管理器和虚拟环境工具,使用Rust编写。

✅ 优点
  1. 极速安装:比pip快10-100倍
  2. 完全兼容pip:可以无缝替换pip
  3. 一体化工具:虚拟环境+包管理
  4. 自动依赖锁定:类似poetry的依赖解析
  5. 智能缓存:重复安装更快
  6. 现代化设计:用户体验优秀
❌ 缺点
  1. 相对较新:2024年发布,生态还在发展
  2. 需要安装:不像venv那样内置
  3. 某些高级功能:可能不如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:数据验证
🎯 学习目标

通过这个案例,你将学会:

  1. 使用uv创建虚拟环境
  2. 快速安装多个依赖
  3. 创建FastAPI应用
  4. 运行和测试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忽略文件
💡 案例总结

通过这个案例,你学会了:

  1. ✅ 使用uv创建虚拟环境
  2. ✅ 快速安装FastAPI相关依赖
  3. ✅ 创建完整的FastAPI应用
  4. ✅ 运行和测试API
  5. ✅ 体验uv的极速安装

3.5 实战案例2:机器学习项目

📋 案例背景

使用uv创建一个机器学习项目,需要安装大量依赖:

  • numpy, pandas:数据处理
  • scikit-learn:机器学习
  • matplotlib, seaborn:可视化
  • jupyter:交互式开发
🎯 学习目标

通过这个案例,你将学会:

  1. 批量安装ML库
  2. 创建ML模型
  3. 训练和评估模型
  4. 使用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忽略文件
💡 案例总结

通过这个案例,你学会了:

  1. ✅ 使用uv批量安装ML库
  2. ✅ 创建机器学习模型
  3. ✅ 训练和评估多个模型
  4. ✅ 可视化结果
  5. ✅ 使用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依赖。

✅ 优点
  1. 跨语言支持:可以管理Python、R、C++等包
  2. 数据科学库完善:预装常用科学计算库
  3. 系统级依赖管理:可以管理非Python依赖
  4. 环境管理强大:创建、克隆、删除环境
  5. 跨平台支持:Windows、macOS、Linux
❌ 缺点
  1. 体积较大:Anaconda完整版约3GB
  2. 相对较慢:比pip和uv慢
  3. 主要面向数据科学:其他场景可能不适用
🎯 适用场景
  • ✅ 数据科学和机器学习项目
  • ✅ 需要跨语言依赖的项目
  • ✅ 需要管理系统级依赖的项目
  • ✅ 团队协作的数据分析项目

4.2 安装与准备

步骤1:安装Miniconda
Windows安装
  1. 访问 https://docs.conda.io/en/latest/miniconda.html
  2. 下载 Windows installer (64-bit)
  3. 运行安装程序
  4. 按提示完成安装(建议勾选"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:交互式开发
🎯 学习目标

通过这个案例,你将学会:

  1. 使用conda创建数据科学环境
  2. 安装数据科学相关库
  3. 创建数据分析脚本
  4. 使用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忽略文件
💡 案例总结

通过这个案例,你学会了:

  1. ✅ 使用conda创建数据科学环境
  2. ✅ 安装数据科学相关库
  3. ✅ 创建股票分析脚本
  4. ✅ 使用Jupyter Notebook
  5. ✅ 导出和复现环境

4.5 实战案例2:深度学习项目

📋 案例背景

使用conda创建深度学习环境,安装PyTorch和相关库。

🎯 学习目标

通过这个案例,你将学会:

  1. 创建深度学习环境
  2. 安装PyTorch
  3. 创建神经网络模型
  4. 训练和评估模型
📝 完整操作步骤
步骤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忽略文件
💡 案例总结

通过这个案例,你学会了:

  1. ✅ 使用conda创建深度学习环境
  2. ✅ 安装PyTorch
  3. ✅ 创建神经网络模型
  4. ✅ 训练和评估模型
  5. ✅ 使用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的功能。

✅ 优点
  1. 自动生成Pipfile和Pipfile.lock
  2. 自动锁定依赖版本
  3. 自动创建和管理虚拟环境
  4. 支持开发依赖分离
  5. 兼容requirements.txt
  6. 简洁的命令行界面
❌ 缺点
  1. 依赖解析较慢
  2. 维护频率降低
  3. 某些情况下可能出现兼容性问题
  4. 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应用,包含数据库、用户认证等功能。

🎯 学习目标

通过这个案例,你将学会:

  1. 使用pipenv创建项目
  2. 管理开发和生产依赖
  3. 创建Flask应用
  4. 运行和测试应用
📝 完整操作步骤
步骤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忽略文件
💡 案例总结

通过这个案例,你学会了:

  1. ✅ 使用pipenv创建项目
  2. ✅ 管理开发和生产依赖
  3. ✅ 创建完整的Flask应用
  4. ✅ 编写和运行测试
  5. ✅ 代码格式化和检查

5.5 实战案例2:API客户端项目

📋 案例背景

创建一个API客户端项目,需要管理多个API的依赖。

🎯 学习目标

通过这个案例,你将学会:

  1. 使用pipenv管理API依赖
  2. 创建同步和异步API客户端
  3. 处理API响应
  4. 错误处理
📝 完整操作步骤
步骤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忽略文件
💡 案例总结

通过这个案例,你学会了:

  1. ✅ 使用pipenv管理API依赖
  2. ✅ 创建同步API客户端
  3. ✅ 创建异步API客户端
  4. ✅ 处理API响应和错误
  5. ✅ 使用环境变量

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依赖管理和打包工具,提供完整的项目生命周期管理。

✅ 优点
  1. 优雅的命令行界面
  2. 完整的项目管理(依赖、构建、发布)
  3. 强大的依赖解析
  4. 使用pyproject.toml作为配置文件
  5. 支持虚拟环境自动管理
  6. 支持依赖组和可选依赖
❌ 缺点
  1. 学习曲线稍陡
  2. 某些高级功能需要熟悉
  3. 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界面、配置管理等功能。

🎯 学习目标

通过这个案例,你将学会:

  1. 使用poetry创建CLI项目
  2. 使用Click和Rich创建美观的CLI
  3. 管理依赖组
  4. 构建和发布工具
📝 完整操作步骤
步骤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):
    """问候命令"""

Logo

这里是“一人公司”的成长家园。我们提供从产品曝光、技术变现到法律财税的全栈内容,并连接云服务、办公空间等稀缺资源,助你专注创造,无忧运营。

更多推荐