Skip to content

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

# 退出虚拟环境
deactivate

virtualenv(第三方,功能更强) ​

bash
pip install virtualenv

# 创建
virtualenv .venv

# 指定 Python 版本
virtualenv -p python3.11 .venv
pip 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/simple

pipenv ​

整合了 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.txt

poetry(推荐) ​

新一代 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 publish

uv(新兴工具) ​

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 freeze

pyproject.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 check

Docker 化 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 + formatterpip install ruff
mypy静态类型检查pip install mypy
pytest测试框架pip install pytest
pre-commitGit 钩子管理pip install pre-commit
pip-tools依赖版本锁定pip install pip-tools
safety依赖安全审计pip install safety
nox自动化测试环境pip install nox
tox多 Python 版本测试pip install tox