Python 环境与包管理
本章涵盖 Python 虚拟环境管理、包管理工具、项目配置(pyproject.toml)以及容器化部署等工程化内容。
虚拟环境
venv(Python 内置)
bash
# 创建虚拟环境
python -m venv .venv
# 激活(Windows)
.venv\Scripts\activate
# 激活(macOS/Linux)
source .venv/bin/activate
# 退出虚拟环境
deactivate# 创建虚拟环境
python -m venv .venv
# 激活(Windows)
.venv\Scripts\activate
# 激活(macOS/Linux)
source .venv/bin/activate
# 退出虚拟环境
deactivatevirtualenv(第三方,功能更强)
bash
pip install virtualenv
# 创建
virtualenv .venv
# 指定 Python 版本
virtualenv -p python3.11 .venvpip install virtualenv
# 创建
virtualenv .venv
# 指定 Python 版本
virtualenv -p python3.11 .venv包管理工具
pip
bash
# 安装包
pip install requests
# 指定版本
pip install requests==2.31.0
# 安装到用户目录(无需虚拟环境)
pip install --user requests
# 导出依赖
pip freeze > requirements.txt
# 从文件安装
pip install -r requirements.txt
# 查看已安装包
pip list
# 查看包信息
pip show requests
# 国内镜像(临时使用)
pip install requests -i https://pypi.tuna.tsinghua.edu.cn/simple
# 设置默认镜像
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple# 安装包
pip install requests
# 指定版本
pip install requests==2.31.0
# 安装到用户目录(无需虚拟环境)
pip install --user requests
# 导出依赖
pip freeze > requirements.txt
# 从文件安装
pip install -r requirements.txt
# 查看已安装包
pip list
# 查看包信息
pip show requests
# 国内镜像(临时使用)
pip install requests -i https://pypi.tuna.tsinghua.edu.cn/simple
# 设置默认镜像
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simplepipenv
整合了 pip 和 virtualenv,使用 Pipfile 管理依赖:
bash
# 安装
pip install pipenv
# 创建虚拟环境并安装包
pipenv install requests
# 安装开发依赖
pipenv install --dev pytest
# 激活虚拟环境
pipenv shell
# 生成 requirements.txt
pipenv requirements > requirements.txt# 安装
pip install pipenv
# 创建虚拟环境并安装包
pipenv install requests
# 安装开发依赖
pipenv install --dev pytest
# 激活虚拟环境
pipenv shell
# 生成 requirements.txt
pipenv requirements > requirements.txtpoetry(推荐)
新一代 Python 包管理和打包工具,使用 pyproject.toml:
bash
# 安装
pip install poetry
# 创建新项目
poetry new my-project
# 初始化已有项目
poetry init
# 安装依赖
poetry add requests
# 安装开发依赖
poetry add --dev pytest
# 安装所有依赖
poetry install
# 激活虚拟环境
poetry shell
# 构建包
poetry build
# 发布到 PyPI
poetry publish# 安装
pip install poetry
# 创建新项目
poetry new my-project
# 初始化已有项目
poetry init
# 安装依赖
poetry add requests
# 安装开发依赖
poetry add --dev pytest
# 安装所有依赖
poetry install
# 激活虚拟环境
poetry shell
# 构建包
poetry build
# 发布到 PyPI
poetry publishuv(新兴工具)
Rust 编写的高性能包管理工具,比 pip 快 10-100 倍:
bash
# 安装
pip install uv
# 创建虚拟环境
uv venv
# 安装包
uv pip install requests
# 从 requirements.txt 安装
uv pip install -r requirements.txt
# 使用 uv 替代 pip(兼容 pip 命令)
uv pip list
uv pip freeze# 安装
pip install uv
# 创建虚拟环境
uv venv
# 安装包
uv pip install requests
# 从 requirements.txt 安装
uv pip install -r requirements.txt
# 使用 uv 替代 pip(兼容 pip 命令)
uv pip list
uv pip freezepyproject.toml(PEP 621)
Python 项目的新标准配置文件,替代 setup.py:
toml
[build-system]
requires = ["setuptools>=68.0", "wheel"]
build-backend = "setupools.build_meta"
[project]
name = "my-project"
version = "0.1.0"
description = "示例项目"
requires-python = ">=3.11"
dependencies = [
"fastapi>=0.109.0",
"sqlalchemy>=2.0.0",
"pydantic>=2.0.0",
]
[project.optional-dependencies]
dev = [
"pytest>=8.0",
"ruff>=0.1.0",
"mypy>=1.8.0",
]
[tool.ruff]
target-version = "py311"
line-length = 100
[tool.mypy]
python_version = "3.11"
strict = true[build-system]
requires = ["setuptools>=68.0", "wheel"]
build-backend = "setupools.build_meta"
[project]
name = "my-project"
version = "0.1.0"
description = "示例项目"
requires-python = ">=3.11"
dependencies = [
"fastapi>=0.109.0",
"sqlalchemy>=2.0.0",
"pydantic>=2.0.0",
]
[project.optional-dependencies]
dev = [
"pytest>=8.0",
"ruff>=0.1.0",
"mypy>=1.8.0",
]
[tool.ruff]
target-version = "py311"
line-length = 100
[tool.mypy]
python_version = "3.11"
strict = true依赖管理最佳实践
bash
# 区分生产与开发依赖
pip install -r requirements.txt
pip install -r requirements-dev.txt
# 使用 pip-tools 锁定版本
pip install pip-tools
pip-compile requirements.in # 生成锁定版本
pip-sync requirements.txt # 同步环境
# 检查依赖安全
pip install safety
safety check# 区分生产与开发依赖
pip install -r requirements.txt
pip install -r requirements-dev.txt
# 使用 pip-tools 锁定版本
pip install pip-tools
pip-compile requirements.in # 生成锁定版本
pip-sync requirements.txt # 同步环境
# 检查依赖安全
pip install safety
safety checkDocker 化 Python 项目
基础 Dockerfile
dockerfile
# 使用官方 Python 镜像
FROM python:3.12-slim
# 设置工作目录
WORKDIR /app
# 设置环境变量
ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1 \
PIP_NO_CACHE_DIR=1
# 先安装依赖(利用 Docker 缓存)
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# 复制项目代码
COPY . .
# 运行
CMD ["python", "main.py"]# 使用官方 Python 镜像
FROM python:3.12-slim
# 设置工作目录
WORKDIR /app
# 设置环境变量
ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1 \
PIP_NO_CACHE_DIR=1
# 先安装依赖(利用 Docker 缓存)
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# 复制项目代码
COPY . .
# 运行
CMD ["python", "main.py"]多阶段构建
dockerfile
# 构建阶段
FROM python:3.12-slim AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --user -r requirements.txt
# 运行阶段
FROM python:3.12-slim
WORKDIR /app
COPY --from=builder /root/.local /root/.local
COPY . .
ENV PATH=/root/.local/bin:$PATH
CMD ["python", "main.py"]# 构建阶段
FROM python:3.12-slim AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --user -r requirements.txt
# 运行阶段
FROM python:3.12-slim
WORKDIR /app
COPY --from=builder /root/.local /root/.local
COPY . .
ENV PATH=/root/.local/bin:$PATH
CMD ["python", "main.py"]docker-compose.yml
yaml
version: "3.9"
services:
app:
build: .
ports:
- "8000:8000"
volumes:
- .:/app
environment:
- DATABASE_URL=postgresql://user:pass@db:5432/db
depends_on:
- db
db:
image: postgres:16-alpine
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: pass
POSTGRES_DB: db
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
postgres_data:version: "3.9"
services:
app:
build: .
ports:
- "8000:8000"
volumes:
- .:/app
environment:
- DATABASE_URL=postgresql://user:pass@db:5432/db
depends_on:
- db
db:
image: postgres:16-alpine
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: pass
POSTGRES_DB: db
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
postgres_data:.dockerignore
dockerignore
__pycache__
*.pyc
.env
.git
.venv
.idea
*.md__pycache__
*.pyc
.env
.git
.venv
.idea
*.md项目配置与环境管理
环境变量
python
# .env 文件管理
# pip install python-dotenv
from dotenv import load_dotenv
import os
load_dotenv()
DATABASE_URL = os.getenv("DATABASE_URL", "sqlite:///default.db")
DEBUG = os.getenv("DEBUG", "false").lower() == "true"# .env 文件管理
# pip install python-dotenv
from dotenv import load_dotenv
import os
load_dotenv()
DATABASE_URL = os.getenv("DATABASE_URL", "sqlite:///default.db")
DEBUG = os.getenv("DEBUG", "false").lower() == "true"多环境配置
python
# config.py
from pydantic_settings import BaseSettings
class Settings(BaseSettings):
app_name: str = "My App"
debug: bool = False
database_url: str = "sqlite:///dev.db"
redis_url: str = "redis://localhost:6379"
class Config:
env_file = ".env"
settings = Settings()# config.py
from pydantic_settings import BaseSettings
class Settings(BaseSettings):
app_name: str = "My App"
debug: bool = False
database_url: str = "sqlite:///dev.db"
redis_url: str = "redis://localhost:6379"
class Config:
env_file = ".env"
settings = Settings()pre-commit 钩子
yaml
# .pre-commit-config.yaml
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.1.0
hooks:
- id: ruff
- id: ruff-format
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.8.0
hooks:
- id: mypy
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer# .pre-commit-config.yaml
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.1.0
hooks:
- id: ruff
- id: ruff-format
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.8.0
hooks:
- id: mypy
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer常用工具一览
| 工具 | 用途 | 安装命令 |
|---|---|---|
| ruff | 极速 linter + formatter | pip install ruff |
| mypy | 静态类型检查 | pip install mypy |
| pytest | 测试框架 | pip install pytest |
| pre-commit | Git 钩子管理 | pip install pre-commit |
| pip-tools | 依赖版本锁定 | pip install pip-tools |
| safety | 依赖安全审计 | pip install safety |
| nox | 自动化测试环境 | pip install nox |
| tox | 多 Python 版本测试 | pip install tox |
Cao Note