当前位置:首页>python>从零搭建现代化 Python 开发环境

从零搭建现代化 Python 开发环境

  • 2026-08-18 23:11:19
从零搭建现代化 Python 开发环境

从零搭建现代化 Python 开发环境

—— 自动控制仿真项目实战指南

从零开始,用最现代的工具链,搭建一个规范、可维护、可复现的 Python 项目。

本教程以「自动控制中的二阶动力学系统仿真」为实战案例,涵盖环境搭建、项目创建、版本管理、代码编写的完整流程。 同时覆盖 Windows 11 与 Ubuntu 24.04 两个系统,在有差异的地方会分别说明。

教程版本: v1.0

更新日期: 2026 年 7 月 25 日

作者: 镜上之窗

许可协议: MIT


写在前面

如果你正在学习 Python,或者准备开始一个科研/工程项目,想必会遇到这样的困惑:

  • 为什么别人的项目目录整整齐齐,我的却一团乱?
  • pip install 装了一堆包,版本冲突了怎么办?
  • 虚拟环境到底是什么?为什么每个人说的都不太一样?
  • 代码写好了,怎么在另一台电脑上跑起来?

这些问题的本质,是缺少一套现代化、标准化的项目工作流

Python 因其简洁易学而成为最受欢迎的编程语言,但"会写代码"和"会做项目"之间隔着一道鸿沟——项目结构怎么组织、依赖怎么管理、代码怎么版本控制、环境怎么复现……这些工程问题,教材上很少系统地教。

本教程就是为填补这道鸿沟而写的。

我们将从零开始,搭建一套完整的 Python 开发环境,并以自动控制中的二阶动力学系统仿真为例,走完从项目创建到代码运行的全过程。你不需要任何前置知识——跟着一步步操作,就能建立一套专业的开发习惯。

我们选择的工具链是:

  • 🖥️ VS Code —— 目前最流行的代码编辑器,插件生态极其丰富
  • ⚡ uv —— 用 Rust 编写的极速 Python 项目管理工具,替代 pip + venv + poetry 的组合
  • 📝 Git —— 行业标准的版本控制工具
  • 🛠️ just —— 便捷的项目任务运行器

写给初学者的话:不必追求一次全部看懂。先跟着操作走一遍,有个整体印象,再回头细想每一步的意义。工程能力是在反复实践中建立的,本文只是你的起点。


目录

  1. 第一章 基础工具安装
    • 1.1 VS Code 安装
    • 1.2 uv 安装与配置
    • 1.3 Git 安装与基础配置
  2. 第二章 VS Code 插件配置
    • 2.1 必备插件
    • 2.2 强烈推荐插件
  3. 第三章 现代化项目结构:src 布局
    • 3.1 什么是 src 布局
    • 3.2 为什么推荐 src 布局
    • 3.3 三个容易混淆的名称
  4. 第四章 使用 uv 创建项目
    • 4.1 初始化项目
    • 4.2 项目结构解读
    • 4.3 pyproject.toml 详解
    • 4.4 安装常用依赖
  5. 第五章 Git 版本控制入门
    • 5.1 初始化仓库
    • 5.2 .gitignore 文件
    • 5.3 Git 核心概念:工作区、暂存区、仓库
    • 5.4 在 VS Code 中使用 Git
    • 5.5 提交信息规范
  6. 第六章 实战:二阶系统阶跃响应
    • 6.1 理论背景
    • 6.2 编写仿真代码
    • 6.3 运行与验证
  7. 第七章 效率提升:just 任务运行器
    • 7.1 just 是什么
    • 7.2 安装 just
    • 7.3 配置 justfile 与 just.py
    • 7.4 使用 just
  8. 附录
    • A. 常见问题(FAQ)
    • B. 常用命令速查表
    • C. 完整项目结构参考
    • D. 进阶学习建议与资源

第一章 基础工具安装

工欲善其事,必先利其器。 本章将搭建 Python 开发的三大基础工具:编辑器、包管理、版本控制。

1.1 VS Code 安装

Visual Studio Code(简称 VS Code)是微软开发的免费、开源代码编辑器。它本身只是一个"壳",真正的强大之处在于海量的插件生态——装什么插件,它就变成什么工具。

🪟 Windows 11

  1. 打开浏览器,搜索 VS Code 官网并访问
  2. 点击 Download for Windows 下载安装包
  3. 双击运行安装程序,一路下一步即可
  4. 重要:在"选择附加任务"这一步,建议勾选以下选项:
    • ✅ 添加到 PATH(允许从终端用 code 命令打开文件)
    • ✅ 创建桌面快捷方式
    • ✅ 将"通过 Code 打开"操作添加到 Windows 资源管理器目录上下文菜单
    • ✅ 将"通过 Code 打开"操作添加到 Windows 资源管理器文件上下文菜单

安装完成后,在开始菜单中找到 VS Code 并打开。

💡 为什么要勾选"添加到 PATH"?PATH 是系统查找可执行程序的路径列表。把 VS Code 加入 PATH 后,你在任意目录的终端里输入 code 就能打开编辑器,输入 code . 就能用 VS Code 打开当前文件夹。这是开发者最常用的操作之一。

🐧 Ubuntu 24.04

方法一:通过官方 apt 仓库安装(推荐)

# 方式一:Snap 一键安装(推荐,最简单)sudo snap install code --classic# 方式二:通过 apt 仓库安装# 请搜索「VS Code Linux install」访问官方文档# 文档中会提供完整的 GPG 密钥和 apt 仓库配置命令

方法二:使用 Snap 安装(更简单,但启动稍慢)

sudo snap install code --classic

安装完成后,在终端输入 code 即可启动。


1.2 uv 安装与配置

uv 是什么?

uv 是 Astral 团队(也是 Ruff 代码检查工具的开发者)用 Rust 编写的 Python 包与项目管理工具。它可以替代传统的 pip + venv + poetry 组合,速度快了一个数量级,而且功能更完整:

功能
传统工具
uv 的替代
包安装
pip
uv pip install
 / uv add
虚拟环境管理
venv / virtualenv
自动管理 .venv
Python 版本管理
pyenv
uv python install
依赖锁定
poetry / pipenv
uv.lock
(自动生成)
项目构建
setuptools / hatchling
uv_build

💡 为什么选择 uv?

  • ⚡ 极速:比 pip 快 10-100 倍(Rust 实现的依赖解析和下载)
  • 🛠️ 一站式:不再需要 pip + venv + pyenv + poetry 的组合
  • 🔒 可复现:自动生成 uv.lock 锁文件,确保团队环境一致
  • 🎯 现代化:原生支持 PEP 517/518/621 等最新 Python 标准

安装 uv

🪟 Windows 11

按下 Win + X,选择"终端"或"PowerShell",执行:

# 方式一:使用 winget(推荐,最简单)winget install astral-sh.uv# 方式二:使用官方安装脚本# 请搜索「uv install」访问 uv 官方文档# 在 Install 章节找到 PowerShell 安装命令并复制执行

安装完成后,关闭当前终端,重新打开一个,输入以下命令验证:

uv --version

🐧 Ubuntu 24.04

打开终端,执行:

# 请搜索「uv install」访问 uv 官方文档# 在 Install 章节找到 Linux 安装命令并复制执行

安装脚本会自动将 uv 安装到 ~/.local/bin/,并写入 shell 配置文件。

安装完成后,执行以下命令让环境变量生效(或重新打开终端):

source ~/.bashrc   # 如果你用 bash# 或者source ~/.zshrc    # 如果你用 zsh

验证安装:

uv --version

💡 什么是"注册环境变量"?uv 安装完成后,需要让系统知道 uv 这个命令在哪里。安装脚本通常已经帮你做了这件事——它会在你的 shell 配置文件里添加一行路径配置。

但配置不会自动应用到已经打开的终端窗口,所以你需要关闭旧终端新开一个,或者手动 source 配置文件。这是初学者最容易踩的坑之一。

配置国内镜像源

uv 默认从国外的 PyPI 服务器下载包,在国内速度可能很慢。我们配置清华镜像源来加速。

uv 的全局配置文件位于:

  • 🪟 Windows%APPDATA%\uv\uv.toml(通常是 C:\Users\你的用户名\AppData\Roaming\uv\uv.toml
  • 🐧 Ubuntu~/.config/uv/uv.toml

🪟 Windows 11 配置方法

在 PowerShell 中执行:

# 创建配置目录(如果不存在)New-Item -ItemType Directory -Path $env:APPDATA\uv -Force# 创建并写入配置文件# 注意:下方的 url 和 python-install-mirror 需要替换为真实的镜像地址# 请搜索「清华大学 TUNA PyPI 镜像」获取@'[[index]]url = "替换为清华 PyPI 镜像地址"default = truepython-install-mirror = "替换为清华 python-build-standalone 镜像地址"'@ | Out-File -FilePath $env:APPDATA\uv\uv.toml -Encoding utf8

🐧 Ubuntu 24.04 配置方法

# 创建配置目录mkdir -p ~/.config/uv# 写入配置文件# 注意:下方的 url 和 python-install-mirror 需要替换为真实的镜像地址# 请搜索「清华大学 TUNA PyPI 镜像」获取cat > ~/.config/uv/uv.toml << 'EOF'[[index]]url = "替换为清华 PyPI 镜像地址"default = truepython-install-mirror = "替换为清华 python-build-standalone 镜像地址"EOF

💡 为什么要换源?PyPI(Python Package Index)是 Python 官方的包仓库,服务器在国外。国内网络环境下直接下载可能很慢甚至超时。

清华大学等机构在国内搭建了镜像站——定期同步官方仓库的内容,你从镜像站下载就和访问国内网站一样快。

default = true 表示将清华源设为默认源。python-install-mirror 则是针对 uv python install 命令的——uv 可以帮你下载管理多个 Python 版本,这个过程也需要加速。

配置完成后,可以用以下命令验证配置是否生效:

uv config list

1.3 Git 安装与基础配置

Git 是目前世界上最流行的分布式版本控制系统。简单来说,它帮你记录代码的每一次改动,随时可以回溯、对比、协作。

💡 为什么需要 Git?Git 能帮你:

  • 📝 记录代码的每一次修改历史
  • 🔄 随时回退到任意历史版本
  • 👥 支持多人协作开发
  • 💾 远程备份代码(推送到 GitHub / Gitee)
  • 🔍 追踪问题和 Bug 的来源

🪟 Windows 11

  1. 搜索 Git 官网,进入下载页面
  2. 双击运行安装程序
  3. 大部分选项保持默认即可,有几处建议调整:
    • Default editor:如果你还不熟悉 Vim,建议改成 "Use Visual Studio Code as Git's default editor"
    • PATH environment:保持默认的 "Git from the command line and also from 3rd-party software"
    • Line ending conversions:保持默认的 "Checkout Windows-style, commit Unix-style line endings"

💡 换行符选项是什么意思?Unix 风格的换行符(\n)是代码世界的通用语言。Windows 的 \r\n 在跨平台协作时会造成不必要的差异。选择此选项可以保证仓库中的代码始终使用 \n,而本地查看时 VS Code 会自动处理显示。

🐧 Ubuntu 24.04

Ubuntu 通常已经预装了 Git。如果没有:

sudo apt update && sudo apt install -y git

基础配置(双平台通用)

安装完 Git 后,第一件事是设置你的用户名和邮箱——每次提交代码时,Git 都会记录"是谁提交的"。

git config --global user.name "你的名字"git config --global user.email "你自己的邮箱"# 设置默认分支名为 main(而非旧默认的 master)git config --global init.defaultBranch main

💡 为什么要设置 init.defaultBranchGit 的默认分支曾长期叫 master。2020 年后,GitHub 和社区逐步采用 main 作为默认分支名。提前设置可以保持与主流一致,避免首次推送时的困惑。

验证安装:

git --version

第二章 VS Code 插件配置

VS Code 本身只是一个文本编辑器,装上插件才会变成强大的 Python IDE。

打开 VS Code,点击左侧边栏的 扩展 图标(四个方块的图标),快捷键 Ctrl+Shift+X,在搜索框中输入插件名称,找到后点击 Install 即可。

下面分"必备"和"强烈推荐"两部分介绍。

2.1 必备插件(4 个)

插件名称
作用说明
搜索关键词
Chinese (Simplified)
将 VS Code 界面汉化,降低学习门槛
Chinese
Python
Microsoft 官方 Python 扩展,提供代码提示、调试、格式化等核心功能
Python
Python Debugger
专业 Python 调试器,提供断点调试、变量监控等高级功能
Python Debugger
Pylance
基于 Pyright 的快速语言服务器,提供精准的类型检查和智能提示
Pylance

💡 为什么需要这些插件?

  • Chinese:中文界面让初学者更易上手
  • Python + Pylance:提供专业级的代码提示和类型检查,写代码时就能发现潜在错误
  • Python Debugger:调试是开发的重要环节,print() 调试法对复杂逻辑效率太低

2.2 强烈推荐插件(7 个)

这些插件不是必须的,但装上之后开发体验会提升一个档次。建议全部安装。

插件名称
作用说明
Ruff
极速 Python 代码检查和格式化工具,比 flake8 + black + isort 更快
Python Environments
图形化管理 Python 虚拟环境,快速切换
Even Better TOML
TOML 配置文件语法高亮和校验(编辑 pyproject.toml 必备)
Markdown All in One
Markdown 编辑增强:快捷键、目录生成、表格格式化
Markdown Preview Enhanced
增强版 Markdown 预览,支持数学公式、流程图、导出 PDF
Markdown Preview Mermaid Support
在 Markdown 中渲染 Mermaid 流程图
markdownlint
Markdown 语法检查,保持文档规范

💡 小建议:可以在 VS Code 设置中开启 "Format On Save"(保存时自动格式化),这样每次按 Ctrl+S 保存,代码就自动变整齐了。


第三章 现代化项目结构:src 布局

在写代码之前,我们先聊聊"项目应该长什么样"。

3.1 什么是 src 布局

Python 项目的源代码组织方式主要有两种。

扁平布局(Flat Layout)——源码直接放在项目根目录:

my_project/├── pyproject.toml├── README.md└── my_project/          # 源码包直接在根目录    ├── __init__.py    └── module.py

src 布局(Src Layout)——源码放在 src/ 子目录下:

my_project/├── pyproject.toml├── README.md└── src/    └── my_project/      # 源码包在 src/ 里面        ├── __init__.py        └── module.py

本教程推荐并使用 src 布局

3.2 为什么推荐 src 布局

初学者可能会问:多套一层 src/ 目录,不是更麻烦吗?

这是一个好问题。src 布局的好处,在项目规模变大后才会体现出来:

1. 强制测试"已安装版本"——这是最核心的原因

如果源码直接放在根目录,那么你在项目根目录下运行 Python 时,import my_project 导入的是当前目录下的源码,而不是虚拟环境中安装的包。

这意味着:你永远测试的是"源文件版本",而不是用户 pip install 之后拿到的"打包版本"。如果你的打包配置有问题(比如漏掉了某个数据文件、某个子模块没被包含进去),你在本地测试一切正常,用户安装后却用不了。

src 布局下,源码放在 src/ 里,项目根目录下没有同名包。import 只能导入虚拟环境里安装的版本。这就迫使你以"用户的视角"来测试,提前发现打包问题。

2. 避免导入歧义

项目根目录下经常会有一些临时脚本,比如 utils.pytest.py。如果你的项目里也有同名模块,扁平布局下就会产生冲突——Python 不知道你想导入哪一个。src 布局把源码"藏"在 src/ 里,根目录可以放心放各种脚本、配置文件。

3. 社区广泛认可

src 布局是 PyPA(Python 打包权威机构)推荐的标准做法,setuptools、hatchling、uv_build 等所有主流构建后端都原生支持。

💡 简单项目可以不用吗? 可以。如果你只是写几个脚本、做个小练习,扁平布局完全够用。但既然我们学习的是"现代化"的工作流,建议从一开始就养成好习惯。

3.3 三个容易混淆的名称

在 src 布局中,有三个不同的"名字"概念,初学者经常搞混:

control-sim/                  # ① 外层文件夹名├── pyproject.toml│   └── name = "control-sim"# ② 项目名└── src/    └── control_sim/          # ③ 源码包名        └── __init__.py
层级
位置
命名规则
作用
① 外层文件夹名
磁盘上的目录名
随便起,合法就行
只是个容器,对 Python 和 uv 没有影响
② 项目名pyproject.toml
 中的 [project].name
允许连字符 -
PyPI 上的安装名,pip install control-sim
③ 源码包名src/
 下面的子目录名
不允许连字符
,用下划线 _
Python import 时用的名字,import control_sim

💡 为什么源码包名不允许连字符? Python 的 import 语句中,连字符 - 是减法运算符。import control-sim 会被 Python 解释为「导入 control,然后减去 sim」,这是一个语法错误。所以源码包名必须用下划线 _ 替代连字符。

关联机制:uv 的构建后端 uv_build 会自动把项目名规范化——转成小写,把连字符 - 和点 . 替换成下划线 _——作为默认的源码包名。所以 name = "control-sim" 自动对应 src/control_sim/


第四章 使用 uv 创建项目

工具都装好了,现在正式创建我们的示例项目——一个自动控制仿真项目。

4.1 初始化项目

打开终端,进入你想存放项目的目录:

# 进入工作目录(根据你的实际情况调整)cd ~/projects    # Linuxcd D:\projects   # Windows

使用 uv 创建项目:

uv init --lib control-sim

参数说明:

  • --lib:创建库项目,使用 src 布局,带有构建系统配置
  • control-sim:项目名

💡 uv init 的三种模式:

命令
布局
适用场景
uv init my-project
扁平布局
简单脚本、一次性任务
uv init --lib my-project
src 布局
库项目(供其他项目导入)
uv init --package my-project
src 布局
应用项目(有命令行入口)

执行完成后,uv 会自动创建 control-sim 文件夹,并生成基础的项目结构。

进入项目目录并用 VS Code 打开:

cd control-simcode .

注意末尾的 . 代表当前目录——这就是勾选"添加到 PATH"的好处。

4.2 项目结构解读

生成的项目目录长这样:

control-sim/├── .python-version    # Python 版本锁定文件├── .venv/             # 虚拟环境目录(自动创建,不用管)├── pyproject.toml     # 项目配置文件(核心)├── README.md          # 项目说明文档├── uv.lock            # 依赖锁定文件(自动生成)└── src/    └── control_sim/        ├── __init__.py        └── py.typed

逐个说明:

  • **.python-version**:记录项目使用的 Python 版本号,uv 会根据这个文件自动选择对应的 Python 解释器。
  • .venv/:虚拟环境目录,所有安装的第三方包都在这里面。不要手动修改里面的内容,也不要提交到 Git。
  • **pyproject.toml**:项目的核心配置文件,包含项目元数据、依赖列表、构建配置等。下面详细讲。
  • **README.md**:项目说明文档,用 Markdown 格式编写。别人打开你的项目,第一个看的就是这个。
  • uv.lock:依赖锁定文件,uv 自动生成,记录每个依赖的精确版本和哈希。应该提交到 Git,确保别人装出来的依赖和你完全一致。
  • **src/control_sim/**:源代码目录,我们的代码都写在这里。
    • __init__.py:标识这个目录是一个 Python 包(可以为空文件)。
    • py.typed:标识这是一个支持类型提示的包,类型检查工具会识别它。

4.3 pyproject.toml 详解

pyproject.toml 是现代化 Python 项目的统一配置文件,由 PEP 518 标准提出。在这之前,项目配置分散在 setup.pysetup.cfgrequirements.txt 等多个文件里,非常混乱。

打开 pyproject.toml,你会看到类似这样的内容:

[project]name = "control-sim"version = "0.1.0"description = "Add your description here"authors = [  { name = "Your Name", email = "你的邮箱" },]readme = "README.md"requires-python = ">=3.12"dependencies = [][build-system]requires = ["uv_build>=0.11.32,<0.12"]build-backend = "uv_build"

主要分为两部分:

[project] —— 项目元数据

  • name:项目名(PyPI 上的安装名)
  • version:版本号(遵循语义化版本规范:主版本.次版本.修订号)
  • description:项目简介
  • authors:作者信息
  • requires-python:要求的最低 Python 版本
  • dependencies:运行时依赖列表,我们接下来会往里加东西

[build-system] —— 构建系统配置

  • requires:构建这个项目需要什么工具
  • build-backend:使用哪个构建后端

这里使用的是 uv_build——uv 官方的构建后端,特点是零配置、速度快,自动识别 src 布局。纯 Python 项目用它就够了。

4.4 安装常用依赖

我们的控制仿真项目需要用到几个常用的科学计算库:

库名
用途
numpy
数值计算基础库,提供高效的数组运算
matplotlib
Python 最主流的绘图库
tqdm
进度条库,循环计算时显示进度

在项目根目录执行:

uv add numpy matplotlib tqdm

这条命令做了以下几件事:

  1. 将 numpymatplotlibtqdm 写入 pyproject.toml 的 dependencies
  2. 解析依赖关系,更新 uv.lock 锁文件
  3. 下载并安装到 .venv 虚拟环境

安装完成后,再执行一次:

uv sync

uv sync 会根据 pyproject.toml 和 uv.lock,确保虚拟环境中的依赖与锁定文件完全一致,同时以可编辑模式将项目本身安装到虚拟环境中。

💡 什么是可编辑模式?可编辑安装(editable install)会在虚拟环境中创建一个链接指向源码目录,修改 src/ 下的代码后无需重新安装即可生效。这对于开发过程非常方便。

验证一下安装是否成功:

uv run python -c "import numpy; import matplotlib; print('All packages imported successfully')"

如果没有报错,说明环境已经就绪。

💡 uv run 是什么?uv run 会自动激活当前项目的虚拟环境,然后执行后面的命令。你不需要手动 source .venv/bin/activate,直接 uv run python xxx.py 就行。这是 uv 非常方便的一点——永远不会因为"忘了激活虚拟环境"而装错包。

uv 工作流总结

创建项目          添加依赖           同步环境            运行代码uv init    →    uv add xxx    →    uv sync       →    uv run python ...
  • **uv add**:添加新依赖(写入配置 + 安装)
  • **uv remove**:移除依赖(从配置删除 + 卸载)
  • **uv sync**:根据配置同步环境(团队成员克隆项目后执行此命令即可还原环境)
  • **uv run**:在项目的虚拟环境中运行命令(不需要手动激活 .venv

第五章 Git 版本控制入门

代码写了就丢、改坏了回不去、多人协作一团糟——这些都是没有版本控制的痛点。Git 就是来解决这些问题的。

5.1 初始化仓库

在项目根目录执行:

git init

Git 会在当前目录创建一个 .git/ 隐藏文件夹,这就是 Git 仓库的数据库。所有的版本历史都存在这里。

5.2 .gitignore 文件

不是所有文件都需要提交到版本控制。虚拟环境、缓存文件、编辑器配置等,每台机器都不一样,提交了反而添麻烦。

在项目根目录创建一个名为 .gitignore 的文件(注意开头的点),写入以下内容:

# ===== Python =====__pycache__/*.py[cod]*$py.class*.so.Pythonbuild/dist/*.egg-info/*.egg# ===== 虚拟环境 =====.venv/venv/env/# ===== 工具缓存 =====.pytest_cache/.mypy_cache/.ruff_cache/.ipynb_checkpoints/htmlcov/.tox/.nox/# ===== 编辑器 =====.vscode/.idea/*.swp*.swo# ===== 系统文件 =====.DS_StoreThumbs.db

💡 为什么要有 .gitignore?Git 的设计哲学是"只跟踪源代码"——也就是人写的、有意义的文件。

虚拟环境 .venv/ 是自动生成的,任何人拿到代码执行 uv sync 就能重建出来,不需要也不应该放进 Git。同理,__pycache__/ 是 Python 自动生成的字节码缓存,每次运行都会变,提交了没有意义。

.gitignore 告诉 Git:"这些文件你忽略就行,不用管。"

5.3 Git 核心概念:工作区、暂存区、仓库

在开始日常使用之前,理解 Git 的三个核心区域非常重要:

工作区(Working Directory)  →  暂存区(Staging Area)  →  本地仓库(Repository)      你编辑的文件                git add 后的文件            git commit 后的快照

💡 什么是暂存区?暂存区(Staging Area)是 Git 的一个核心概念。你可以把它理解为"提交前的准备区"。

不是所有修改都要一次性提交。比如你同时改了 A 功能和 B 功能,但想分成两次提交(方便后续追溯),就可以先暂存 A 相关的文件,提交一次;再暂存 B 相关的文件,再提交一次。

初学者可能觉得多此一举,但这是 Git 精细管理变更的基础。用多了就会 appreciate 这个设计。

5.4 在 VS Code 中使用 Git

VS Code 左侧边栏有一个 源代码管理 图标(分支形状,快捷键 Ctrl+Shift+G)。点击它就能看到 Git 面板。

基本操作流程是:

  1. 修改文件 → 文件出现在"更改"列表
  2. 暂存 → 点击文件旁边的 + 号,把文件加入暂存区
  3. 提交 → 在上方输入提交信息,点击"提交"按钮
操作
方法
暂存文件
点击文件旁的 + 号
暂存所有
点击"更改"旁的 + 号
取消暂存
点击已暂存文件旁的 - 号
提交
输入提交信息,点击  按钮
查看差异
点击文件名,VS Code 会打开左右对比视图
撤销修改
点击文件旁的  图标

5.5 提交信息规范

好的提交信息应该简洁明了地说明"这次提交做了什么"。推荐遵循 Conventional Commits 规范:

<类型>: <简要描述>

常用类型:

类型
含义
示例
feat
新功能
feat: 添加二阶系统仿真模块
fix
修复 bug
fix: 修复 matplotlib 中文显示问题
docs
文档更新
docs: 更新 README 安装说明
style
代码格式(不影响功能)
style: 统一代码缩进风格
refactor
重构
refactor: 提取公共绘图函数
test
添加测试
test: 添加阶跃响应单元测试
chore
构建/工具变更
chore: 更新依赖版本

现在我们来做项目的第一次提交:

# 暂存所有文件git add .# 查看即将提交的文件(可选,用于确认)git status# 首次提交git commit -m "feat: 初始化项目结构与依赖配置"

提交完成后,你的第一个版本就被永久记录下来了。以后任何时候想回到这个状态,都可以通过 Git 找回。

💡 良好的 Git 实践建议:

  • 频繁提交,每次提交完成一个小功能
  • 提交消息清晰明确,描述"做了什么"而非"怎么做的"
  • 使用分支进行新功能开发
  • 定期推送到远程仓库(如 GitHub / Gitee)

第六章 实战:二阶系统阶跃响应

环境搭好了,版本控制也建好了,现在写点真东西。

我们来实现一个经典的自动控制案例——二阶动力学系统的单位阶跃响应,并用 matplotlib 画出曲线。

6.1 理论背景

二阶系统是控制理论中最基础、最重要的系统模型之一。许多实际系统(如弹簧-阻尼器、电机、飞行器姿态控制)都可以近似为二阶系统。

它的传递函数标准形式为:

其中:

  • (omega_n):自然频率(系统固有的振荡频率,单位 rad/s)
  • (zeta):阻尼比(无量纲,决定系统的振荡特性)

📖 延伸阅读:可搜索「二阶系统」「传递函数」「控制理论」等关键词深入了解。

不同的阻尼比决定了系统的响应特性:

阻尼比 
系统类型
阶跃响应特征
无阻尼
等幅振荡,永不停止
欠阻尼
衰减振荡后趋于稳态(最常见)
临界阻尼
无振荡,最快收敛
过阻尼
无振荡,缓慢收敛

我们将使用解析解来计算不同阻尼比下的阶跃响应,并绘制对比曲线。

6.2 编写仿真代码

在 src/control_sim/ 目录下创建两个文件:

文件一:second_order.py —— 仿真核心逻辑

"""二阶动力学系统仿真模块。实现标准二阶系统的单位阶跃响应计算。传递函数: G(s) = ω_n² / (s² + 2ζω_n s + ω_n²)"""from __future__ import annotationsimport numpy as npdefstep_response(    zeta: float,    omega_n: float,    t_end: float = 10.0,    num_points: int = 1000,) -> tuple[np.ndarray, np.ndarray]:"""计算二阶系统的单位阶跃响应。    根据阻尼比的不同,使用对应的解析解公式。    Args:        zeta: 阻尼比 (无量纲)        omega_n: 自然频率 (rad/s)        t_end: 仿真结束时间 (秒)        num_points: 时间采样点数    Returns:        time: 时间数组        output: 系统输出数组(无量纲)    """    time = np.linspace(0, t_end, num_points)if zeta < 1.0:# 欠阻尼:振荡衰减        omega_d = omega_n * np.sqrt(1 - zeta**2)  # 阻尼自然频率        phi = np.arccos(zeta)                       # 相位角        output = 1.0 - (np.exp(-zeta * omega_n * time) / np.sqrt(1 - zeta**2)) \                 * np.sin(omega_d * time + phi)elif abs(zeta - 1.0) < 1e-9:# 临界阻尼:快速无振荡        output = 1.0 - np.exp(-omega_n * time) * (1.0 + omega_n * time)else:# 过阻尼:缓慢无振荡        sqrt_term = np.sqrt(zeta**2 - 1.0)        pole1 = -zeta * omega_n + omega_n * sqrt_term        pole2 = -zeta * omega_n - omega_n * sqrt_term        A = omega_n**2 / (pole1 * pole2)        B = omega_n**2 / (pole1 * (pole1 - pole2))        C = omega_n**2 / (pole2 * (pole2 - pole1))        output = A + B * np.exp(pole1 * time) + C * np.exp(pole2 * time)return time, outputdefcompute_settling_time(    t: np.ndarray,    y: np.ndarray,    threshold: float = 0.02,) -> float | None:"""计算调节时间。    调节时间定义为:系统响应进入并保持在稳态值 ±threshold 范围内的时间。    这是评价控制系统性能的重要指标之一。    Args:        t: 时间数组        y: 响应数组        threshold: 稳态误差带(默认 2%,即 ±2%)    Returns:        调节时间(秒),如果从未进入误差带则返回 None    """    steady_state = y[-1]    lower = steady_state * (1 - threshold)    upper = steady_state * (1 + threshold)# 从后向前搜索,找到最后一个超出误差带的时刻for i in range(len(t) - 1-1-1):if y[i] < lower or y[i] > upper:if i < len(t) - 1:return t[i + 1]returnNonereturn t[0]

💡 **关于 compute_settling_time**:调节时间(settling time)是控制系统中衡量响应速度的重要指标。它表示系统输出进入并保持在稳态值 ±2% 范围内所需的时间。在工程实践中,这个指标比"到达稳态"更有意义,因为我们需要知道系统"稳定下来"的确切时刻。

文件二:plot_step.py —— 绘图入口

"""绘制不同阻尼比下的二阶系统阶跃响应曲线。"""from __future__ import annotationsimport matplotlib.pyplot as pltimport numpy as npfrom matplotlib.font_manager import FontProperties, findfontfrom control_sim.second_order import compute_settling_time, step_responsedef_configure_chinese_font() -> str:"""自动检测并配置 matplotlib 中文字体。    按优先级依次尝试系统中常见的中文字体,找到第一个可用的即配置并返回。    如果没有找到任何中文字体,返回空字符串并给出提示。    Returns:        使用的字体名称,未找到则返回空字符串    """    candidates = ["Microsoft YaHei",        # Windows 11 默认"SimHei",                 # Windows 经典黑体"WenQuanYi Micro Hei",   # Linux 文泉驿微米黑"Noto Sans CJK SC",      # Linux Noto 字体    ]for name in candidates:try:# 如果 findfont 返回的不是默认字体,说明找到了if findfont(FontProperties(family=name)) != findfont(FontProperties()):                plt.rcParams["font.sans-serif"] = [name] + plt.rcParams["font.sans-serif"]                plt.rcParams["axes.unicode_minus"] = Falsereturn nameexcept Exception:continue# 未找到中文字体,给出提示    plt.rcParams["axes.unicode_minus"] = False    print("⚠️  未找到中文字体,图表中的中文可能显示为方块。")    print("   Windows 用户通常无需担心;Linux 用户可执行:sudo apt install fonts-wqy-microhei")return""defmain() -> None:"""主函数:计算并绘制阶跃响应曲线。"""# ===== 配置中文字体 =====    font_name = _configure_chinese_font()if font_name:        print(f"✓ 使用中文字体: {font_name}")# ===== 参数设置 =====    omega_n = 2.0 * np.pi       # 自然频率:2π rad/s    zeta_list = [0.20.50.7071.01.5]  # 不同阻尼比    t_end = 5.0# 仿真时长# ===== 创建画布 =====    fig, ax = plt.subplots(figsize=(127), dpi=120)# ===== 逐个计算并绘图 =====for zeta in zeta_list:        t, y = step_response(zeta, omega_n, t_end=t_end)# 构造图例标签        label = f"ζ = {zeta}"if zeta < 1.0:            label += "(欠阻尼)"elif abs(zeta - 1.0) < 1e-9:            label += "(临界阻尼)"else:            label += "(过阻尼)"        ax.plot(t, y, linewidth=2, label=label)# 标注调节时间(仅对有稳态值的情况)if zeta > 0:            ts = compute_settling_time(t, y, threshold=0.02)if ts isnotNoneand ts < t_end:                ax.axvline(x=ts, color=ax.lines[-1].get_color(), linestyle="--", alpha=0.3)                ax.annotate(f"ts={ts:.1f}s",                    xy=(ts, 1.0),                    xytext=(ts + 0.150.55 + zeta * 0.15),                    fontsize=8,                    color=ax.lines[-1].get_color(),                    arrowprops=dict(arrowstyle="->", alpha=0.4),                )# ===== 图形装饰 =====    ax.axhline(y=1.0, color="gray", linestyle=":", linewidth=1, alpha=0.5)    ax.text(t_end * 0.931.02"稳态值", fontsize=9, color="gray", ha="center")    ax.set_title(f"二阶系统单位阶跃响应(ωₙ = {omega_n:.1f} rad/s)", fontsize=16, pad=15)    ax.set_xlabel("时间 t (秒)", fontsize=13)    ax.set_ylabel("输出 y(t)", fontsize=13)    ax.grid(True, linestyle="--", alpha=0.6)    ax.legend(fontsize=11, loc="right")    ax.set_xlim(0, t_end)    ax.set_ylim(bottom=-0.1)    ax.tick_params(labelsize=11)    fig.tight_layout()# ===== 保存并显示 =====    output_path = "step_response.png"    fig.savefig(output_path, dpi=150, bbox_inches="tight")    print(f"✓ 图片已保存为 {output_path}")    plt.show()if __name__ == "__main__":    main()

💡 代码亮点说明:

  1. 类型注解:使用 floatnp.ndarray 等类型注解,提高代码可读性和 IDE 支持
  2. 文档字符串:每个函数都有清晰的 docstring,说明参数和返回值
  3. 跨平台中文字体检测_configure_chinese_font() 自动检测操作系统并选择合适的字体,Windows 用户和 Linux 用户无需额外配置
  4. 调节时间标注:自动计算并标注每条曲线的调节时间,直观展示系统性能差异
  5. **from __future__ import annotations**:启用延迟求解类型注解,支持 float | None 等现代语法

6.3 运行与验证

在项目根目录执行:

uv run python -m control_sim.plot_step

💡 -m 是什么意思?-m 表示以模块方式运行。python -m control_sim.plot_step 等价于"找到 control_sim.plot_step 这个模块,执行它的 __main__ 部分"。

为什么不直接 python src/control_sim/plot_step.py?因为直接运行脚本文件时,Python 的模块搜索路径可能不对,导致 import control_sim.second_order 失败。用 -m 方式运行是更规范的做法。

如果一切正常,你会看到:

  1. 终端输出字体检测信息
  2. 弹出一个图形窗口,显示五条不同阻尼比的阶跃响应曲线
  3. 项目根目录下生成 step_response.png 图片

观察曲线,你可以直观地看到:

  • 阻尼比越小,超调量越大,振荡越剧烈
  • 临界阻尼是"刚好不振荡"的边界
  • 过阻尼响应慢,但最平稳

这就是控制理论中"响应速度"与"稳定性"的经典权衡。

现在提交我们的仿真代码:

git add .git commit -m "feat: 添加二阶系统阶跃响应仿真与可视化"

第七章 效率提升:just 任务运行器

项目开发中,经常有一些重复性的命令操作:清理缓存、运行测试、启动服务……每次都敲一长串命令很麻烦。

just 是一个用 Rust 编写的命令运行器(类似 Make,但更简单、更现代)。你可以把常用命令写在 justfile 里,然后用 just 命令名 来执行。

7.1 just 是什么

简单理解:just 就是一个"项目命令快捷方式管理器"。

比如你定义了:

clean:    uv run python just.py clean

以后只需要输入 just clean,就会自动执行后面那串命令。

💡 什么时候需要清理缓存?最常见的场景是使用 Numba 进行 JIT 加速时。Numba 会把编译后的机器码缓存起来,如果缓存损坏或版本不兼容,可能导致奇怪的错误——比如修改了代码但行为没有变化。这时候执行 just clean 清理所有缓存,就能确保下次运行时重新编译。

7.2 安装 just

推荐通过 uv 的工具管理功能安装:

uv tool install rust-just

💡 uv tool install 是什么? 它会将工具安装到一个独立的隔离环境中,然后在全局可用。这类似于 pipx,但由 uv 管理,速度更快。安装后,just 命令可以在任何目录下直接使用,无需激活虚拟环境。

安装完成后验证:

just --version

💡 为什么用 uv tool install 而不是系统包管理器?

  • 跨平台一致:Windows 和 Linux 都是同一条命令安装
  • 隔离环境:每个工具都有自己的独立环境,不会污染系统 Python
  • 统一管理:uv tool list 查看所有工具,uv tool upgrade 一键升级

7.3 配置 justfile 与 just.py

以下配置来自作者长期的 Python 开发实践,已在多个项目中验证。

第一步:创建 justfile

在项目根目录创建名为 justfile 的文件(没有后缀名),写入:

# 默认显示帮助default: list# 清理项目缓存文件clean:    uv run python just.py clean# 查看当前环境信息info:    uv run python just.py info# 显示可用命令列表list:    uv run python just.py list

⚠️ 注意:justfile 中缩进必须使用 Tab(制表符),不能用空格。Windows 下创建文件时注意不要变成 justfile.txt

第二步:创建 just.py

将以下代码保存到项目根目录(和 pyproject.toml 同级):

"""项目管理辅助工具提供缓存清理、环境信息查询、帮助文档等功能。"""from __future__ import annotationsimport platformimport shutilimport sysfrom collections.abc import Callablefrom dataclasses import dataclass, fieldfrom pathlib import Path# ==================== 配置定义 ====================@dataclassclassCleanConfig:"""缓存清理的配置项。"""    max_display: int = 10    venv_dir: str = ".venv"    cache_patterns: set[str] = field(        default_factory=lambda: {"__pycache__",".pytest_cache",".mypy_cache",".ruff_cache",".ipynb_checkpoints","htmlcov",".tox",".nox",        }    )CLEAN_CONFIG = CleanConfig()# ==================== 核心业务逻辑 ====================defscan_cache_dirs(root: Path, config: CleanConfig) -> list[Path]:"""扫描给定根目录下的所有缓存目录。"""    targets = []    patterns = config.cache_patterns    venv_dir = config.venv_dirfor pattern in patterns:for p in root.rglob(pattern):# 跳过虚拟环境目录中的缓存if any(part.casefold() == venv_dir.casefold() for part in p.parts):continue            targets.append(p)return targetsdefremove_paths(paths: list[Path]) -> int:"""批量删除路径,并返回成功删除的数量。"""    success = 0for p in paths:try:if p.is_dir():                shutil.rmtree(p)else:                p.unlink()            success += 1except Exception as e:  # noqa: BLE001            print(f"  ⚠️ 无法删除 {p.name}{e}")return success# ==================== 功能函数 ====================defclean() -> None:"""清理项目缓存"""    root = Path.cwd()    targets = scan_cache_dirs(root, CLEAN_CONFIG)ifnot targets:        print("✅ 未发现缓存目录,环境已是干净的。")return    max_display = CLEAN_CONFIG.max_display    targets.sort(key=lambda x: len(x.parts), reverse=True)    print(f"📁 发现 {len(targets)} 个缓存目录:")for p in targets[:max_display]:        print(f"  🗑️  {p.relative_to(root)}")if len(targets) > max_display:        print(f"  ... 还有 {len(targets) - max_display} 个未显示")    print("\n正在清理...")    success_count = remove_paths(targets)    print(f"✅ 成功清理 {success_count} 个目录。")definfo() -> None:"""显示环境信息"""    print("🖥️  环境信息:")    print(f"  🐍 Python  : {platform.python_version()} ({sys.executable})")    print(f"  📂 工作目录 : {Path.cwd()}")    print(f"  💻 操作系统 : {platform.system()}{platform.release()}")    print(f"  🏷️  主机名  : {platform.node()}")defhelp_menu() -> None:"""显示帮助菜单"""    print("📋 可用命令:\n")    max_len = max(len(k) for k in COMMANDS)for name, func in COMMANDS.items():        desc = "无描述"if func.__doc__:            desc = func.__doc__.strip().split("\n")[0]        print(f"  {name.ljust(max_len)}  : {desc}")# ==================== 路由注册 ====================COMMANDS: dict[str, Callable] = {"clean": clean,"info": info,"list": help_menu,}# ==================== 程序入口 ====================defmain() -> None:"""程序入口"""    args = sys.argv[1:]    cmd_name = args[0if args else"list"if cmd_name in COMMANDS:        COMMANDS[cmd_name]()else:        print(f"❌ 未知命令: {cmd_name}\n")        help_menu()        sys.exit(1)if __name__ == "__main__":    main()

7.4 使用 just

在项目根目录下,直接输入:

# 显示所有可用命令just# 清理缓存just clean# 查看环境信息just info

示例输出——just clean

📁 发现 15 个缓存目录:  🗑️  src/control_sim/__pycache__  🗑️  tests/__pycache__  🗑️  .ruff_cache  ... 还有 12 个未显示正在清理...✅ 成功清理 15 个目录。

示例输出——just info

🖥️  环境信息:  🐍 Python  : 3.12.0 (/path/to/.venv/bin/python)  📂 工作目录 : /path/to/control-sim  💻 操作系统 : Linux 6.5.0-28-generic  🏷️  主机名  : your-hostname

现在提交我们的工具配置:

git add .git commit -m "chore: 添加 just 任务运行器配置"

附录

A. 常见问题(FAQ)

Q1:uv 命令找不到怎么办?

这是环境变量没有生效的问题。

  • 🪟 Windows:关闭所有终端窗口,重新打开一个。如果还不行,检查用户环境变量的 Path 中是否包含 %USERPROFILE%\.local\bin
  • 🐧 Ubuntu:执行 source ~/.bashrc(或对应 shell 的配置文件)。如果是通过桌面图标打开的 VS Code 终端,可能需要注销重登。

Q2:import control_sim 报错 ModuleNotFoundError?

常见原因有三个:

  1. **没有用 uv run**:直接 python xxx.py 用的是系统 Python,不是项目的虚拟环境。加上 uv run 前缀。
  2. 项目没有安装到虚拟环境:执行 uv sync,确保项目以可编辑模式安装。
  3. 包名写错了:import 用的是源码包名(带下划线的 control_sim),不是项目名 control-sim

Q3:matplotlib 中文还是方块?

  1. 确认系统安装了中文字体(Linux 需要手动装:sudo apt install fonts-wqy-microhei
  2. 确认 _configure_chinese_font() 函数正常执行(查看终端输出)
  3. 清除 matplotlib 字体缓存:删除 ~/.cache/matplotlib/ 目录(Linux)或 %USERPROFILE%\.matplotlib\(Windows),然后重新运行

Q4:虚拟环境在哪?我怎么激活它?

uv 创建的虚拟环境默认在项目根目录的 .venv/ 文件夹里。

你其实不需要手动激活——uv run 会自动用它。如果确实需要手动激活:

# Windows PowerShell.venv\Scripts\Activate.ps1# Windows Git Bashsource .venv/Scripts/activate# Ubuntusource .venv/bin/activate

激活后终端提示符前面会出现 (.venv) 标识。退出用 deactivate

Q5:uv.lock 文件要提交到 Git 吗?

要提交。

uv.lock 记录了所有依赖的精确版本号和哈希值。别人拿到你的项目,执行 uv sync 就能装出和你完全一样的依赖环境,避免"我这能跑你那跑不了"的尴尬。

Q6:.venv 目录好大,可以删吗?

可以删,不会丢代码。删了之后执行 uv sync 会根据 uv.lock 完整重建出来。

Q7:uv sync 很慢怎么办?

确认已配置国内镜像源(见 1.2 节)。配置后下载速度会显著提升。


B. 常用命令速查表

uv 命令

命令
说明
uv init --lib 项目名
创建库项目(src 布局)
uv init --package 项目名
创建应用项目(src 布局)
uv add 包名
添加依赖
uv add --dev 包名
添加开发依赖
uv remove 包名
删除依赖
uv sync
同步依赖(安装项目)
uv run python 文件.py
运行 Python 脚本
uv run python -m 模块名
以模块方式运行
uv pip list
查看已安装的包
uv python install 3.12
安装指定 Python 版本
uv tool install 工具名
全局安装命令行工具

Git 命令

命令
说明
git init
初始化仓库
git status
查看状态
git add .
添加所有修改到暂存区
git add <文件>
添加指定文件到暂存区
git commit -m "消息"
提交暂存区的修改
git log --oneline
查看简洁的提交历史
git diff
查看未暂存的修改
git diff --staged
查看已暂存的修改
git restore <文件>
丢弃工作区的修改
git restore --staged <文件>
取消暂存
git branch 分支名
创建分支
git checkout 分支名
切换分支
git merge 分支名
合并分支

just 命令

命令
说明
just
 / just list
显示所有可用命令
just clean
清理项目缓存
just info
查看环境信息

C. 完整项目结构参考

完成本教程后,你的项目目录应该如下所示:

control-sim/├── .python-version          # Python 版本锁定(uv 自动生成)├── .gitignore               # Git 忽略规则├── pyproject.toml           # 项目配置(元数据、依赖、构建系统)├── uv.lock                  # 依赖锁文件(uv 自动生成)├── README.md                # 项目说明├── justfile                 # just 任务管理配置├── just.py                  # just 任务管理脚本├── step_response.png        # 生成的阶跃响应图├── src/                     # 源代码目录│   └── control_sim/         # 源码包名(import control_sim)│       ├── __init__.py      # 包标识│       ├── py.typed         # 类型标记(uv 自动生成)│       ├── second_order.py  # 二阶系统仿真模块│       └── plot_step.py     # 绘图入口└── .venv/                   # 虚拟环境(自动生成,不追踪)

关键文件说明

文件
作用
是否提交到 Git
pyproject.toml
项目元数据和依赖配置
✅ 是
uv.lock
依赖锁定文件,确保环境可复现
✅ 是
.python-version
Python 版本锁定
✅ 是
.gitignore
Git 忽略配置
✅ 是
just.py
项目管理工具
✅ 是
justfile
just 命令配置
✅ 是
.venv/
虚拟环境目录
❌ 否(在 .gitignore 中)
__pycache__/
Python 字节码缓存
❌ 否(在 .gitignore 中)

D. 进阶学习建议与资源

恭喜你完成了这篇教程!回顾一下,你已经学会了:

  • ✅ 安装并配置 VS Code、uv、Git 三大基础工具
  • ✅ 理解并使用现代化的 src 项目布局
  • ✅ 用 uv 创建项目、管理依赖、锁定版本
  • ✅ 用 Git 做版本控制,在 VS Code 中进行提交
  • ✅ 编写并运行一个二阶系统仿真程序,绘制中文标注的曲线图
  • ✅ 用 just 管理常用项目命令

这是一套完整的、现代化的 Python 项目工作流。掌握了它,你以后新建任何 Python 项目都有了标准的起点。

推荐学习路径

阶段一:巩固基础(1-2 周)

  • [ ] 熟悉 Python 类型系统(typing 模块)
  • [ ] 学习 pytest 编写单元测试
  • [ ] 掌握 Ruff 代码检查和格式化
  • [ ] 深入理解 Git 分支和合并

阶段二:工程化实践(1-2 个月)

  • [ ] 学习持续集成(CI/CD,如 GitHub Actions)
  • [ ] 配置自动化测试和代码覆盖率
  • [ ] 编写完整的 API 文档(使用 Sphinx 或 MkDocs)
  • [ ] 探索性能优化技巧(如 Numba、Cython)

阶段三:专业级项目(3-6 个月)

  • [ ] 参与开源项目贡献代码
  • [ ] 学习异步编程(asyncio)
  • [ ] 了解容器化部署(Docker)
  • [ ] 尝试打包发布到 PyPI

推荐资源

官方文档

  • Python 官方文档
  • uv 官方文档
  • VS Code 官方文档
  • Git 官方文档

书籍推荐

  • 《流畅的 Python(第 2 版)》—— Luciano Ramalho
  • 《Python 编程:从入门到实践》—— Eric Matthes
  • 《Effective Python》—— Brett Slatkin

在线资源

  • Real Python —— 高质量 Python 教程
  • Python 官方教程
  • Stack Overflow —— 问题解答
  • GitHub —— 代码托管和协作

写在最后

编程是一门实践的艺术,最好的学习方式就是动手做。工具会不断进化,但好的习惯是持久的:使用虚拟环境隔离依赖、用锁文件确保可复现、用版本控制追踪变更、用项目结构表达意图。

一步一步来,工程能力是在实践中积累的。祝编码愉快!🎉

最新文章

随机文章

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-08-21 20:54:29 HTTP/2.0 GET : https://f.mffb.com.cn/a/506883.html
  2. 运行时间 : 0.285921s [ 吞吐率:3.50req/s ] 内存消耗:5,237.80kb 文件加载:140
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=122351f1cd630864d4d09b9f6d2df53f
  1. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_static.php ( 4.90 KB )
  7. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  10. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  11. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  12. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  13. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  14. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  15. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  16. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  17. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  18. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  19. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  21. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  22. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/provider.php ( 0.19 KB )
  23. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  24. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  25. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  26. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/common.php ( 0.03 KB )
  27. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  28. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  29. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/app.php ( 0.95 KB )
  30. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cache.php ( 0.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/console.php ( 0.23 KB )
  32. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cookie.php ( 0.56 KB )
  33. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/database.php ( 2.48 KB )
  34. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  35. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/filesystem.php ( 0.61 KB )
  36. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/lang.php ( 0.91 KB )
  37. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/log.php ( 1.35 KB )
  38. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/middleware.php ( 0.19 KB )
  39. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/route.php ( 1.89 KB )
  40. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/session.php ( 0.57 KB )
  41. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/trace.php ( 0.34 KB )
  42. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/view.php ( 0.82 KB )
  43. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/event.php ( 0.25 KB )
  44. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  45. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/service.php ( 0.13 KB )
  46. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/AppService.php ( 0.26 KB )
  47. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  48. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  49. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  50. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  51. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  52. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/services.php ( 0.14 KB )
  53. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  54. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  55. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  56. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  57. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  58. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  59. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  60. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  61. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  62. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  63. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  64. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  65. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  66. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  67. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  68. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  69. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  70. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  71. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  72. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  73. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  74. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  75. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  76. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  77. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  78. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  79. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  80. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  81. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  82. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  83. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/Request.php ( 0.09 KB )
  84. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  85. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/middleware.php ( 0.25 KB )
  86. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  87. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  88. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  89. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  90. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  91. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  92. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  93. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  94. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  95. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  96. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  97. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  98. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  99. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/route/app.php ( 1.72 KB )
  100. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  101. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  102. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  103. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/controller/Index.php ( 4.81 KB )
  104. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/BaseController.php ( 2.05 KB )
  105. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  106. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  108. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  109. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  110. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  111. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  112. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  113. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  114. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  115. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  116. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  117. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  118. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  119. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  120. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  121. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  122. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  123. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  124. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  125. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  126. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  127. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  128. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  129. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  130. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  131. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  132. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  133. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  134. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  135. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  136. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  137. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  138. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  139. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/runtime/temp/067d451b9a0c665040f3f1bdd3293d68.php ( 11.98 KB )
  140. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.001125s ] mysql:host=127.0.0.1;port=3306;dbname=f_mffb;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.001618s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000836s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000761s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.001468s ]
  6. SELECT * FROM `set` [ RunTime:0.000614s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.001468s ]
  8. SELECT * FROM `article` WHERE `id` = 506883 LIMIT 1 [ RunTime:0.009777s ]
  9. UPDATE `article` SET `lasttime` = 1787316869 WHERE `id` = 506883 [ RunTime:0.037516s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 66 LIMIT 1 [ RunTime:0.000914s ]
  11. SELECT * FROM `article` WHERE `id` < 506883 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.001408s ]
  12. SELECT * FROM `article` WHERE `id` > 506883 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.007741s ]
  13. SELECT * FROM `article` WHERE `id` < 506883 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.002046s ]
  14. SELECT * FROM `article` WHERE `id` < 506883 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.026969s ]
  15. SELECT * FROM `article` WHERE `id` < 506883 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.023924s ]
0.289565s