python 入门第一天

31 阅读6分钟

Python & FastAPI 全栈监控系统学习笔记 (小白保姆级教程)

这份笔记是专门为您定制的。考虑到您刚接触 Python,我会把每一个复杂的知识点都拆碎了,用大白话生活中的例子来讲,并且会对照着我们项目里的真实代码,一行一行地解释。


第一章:Python 基础语法(在这个项目里用到的)

1.1 字典解包 ** —— 把“包裹”炸开

routes.py 里,您看到了这样的代码:

response_data = SystemMetricsResponse(
    **result.model_dump(...)
)

这是什么意思? 想象一下,你有一个装满东西的快递包裹(字典),里面有苹果、梨、香蕉。 你要把这些水果分给三个小朋友(函数参数),他们每个人只拿一样。

  • 没有 ** (错误写法): 你直接把整个包裹扔给了第一个小朋友。 小朋友会哭:“我要的是苹果,你给我这么大一个箱子干嘛?我拿不动!” (程序报错:参数类型不匹配)

  • ** (正确写法): 你在分发之前,先用剪刀把包裹拆开(解包),把苹果递给小明,把梨递给小红,把香蕉递给小刚。 小朋友很开心,每个人都拿到了自己想要的东西。 (程序正常运行)

代码对照:

  • 包裹result.model_dump(...) 产生的字典 {'cpu': 10, 'mem': 20}
  • 小朋友SystemMetricsResponse 需要的参数 cpu=..., mem=...
  • **:就是那把剪刀。

1.2 类型提示 ->: —— 给代码贴标签

routes.py 里:

def get_repo(request: Request) -> Repository[SystemMetricsModel]:

这行代码如果不写标签,Python 也能跑,但写了标签有两个好处:

  1. 给编辑器看:编辑器知道 request 是个 Request 对象,当你敲 request. 时,它会弹出提示框告诉你有哪些方法可以用。
  2. 给你看:你一眼就能知道这个函数需要啥、返回啥。

逐字翻译:

  • request: Request
    • “这个叫 request 的参数,它的身份是 Request 类型的。”
    • 就像工牌上写着“职位:经理”。
  • -> Repository
    • “这个函数执行完,会吐出一个 Repository 类型的东西。”
    • 就像菜单上写着“出口:取餐处”。
  • [SystemMetricsModel]
    • 这是泛型。意思是这个仓库(Repository)不是空的,也不是装杂物的,它是专门用来装 SystemMetricsModel 这种数据的。
    • 就像箱子上贴着标签:“易碎品:SystemMetricsModel”。

1.3 列表推导式 —— 一行代码搞定循环

parse_gpu_details 函数里:

return [GPUMetric(**item) for item in data]

这是什么神仙写法? 这其实是把三行代码压缩成了一行。

如果不这么写,原本是这样的:

result_list = []              # 1. 先准备一个空篮子
for item in data:             # 2. 挨个把 data 里的东西(item)拿出来
    obj = GPUMetric(**item)   # 3. 把 item 加工一下,变成 GPUMetric 对象
    result_list.append(obj)   # 4. 扔进篮子里
return result_list            # 5. 把篮子交出去

列表推导式就是说: “给我一个新的列表,里面的东西是把 data 里的每个 item 都拿去做成 GPUMetric 之后的结果。”


第二章:数据是怎么流转的?(JSON 的奥秘)

在这个项目里,数据像变魔术一样变来变去,一会儿是对象,一会儿是字符串,一会儿是字典。我们要搞清楚它在每个阶段到底长啥样。

场景:从显卡采集到网页显示

第1步:采集 (Python 列表)

  • 地点monitor.py -> get_gpu_metrics_via_ssh
  • 形态List[Dict] (列表里装字典)
  • 样子
    [
        {"index": "0", "temp": 45}, 
        {"index": "1", "temp": 50}
    ]
    
  • 状态:活的,可以用代码 data[0]['temp'] 去读。

第2步:存库 (JSON 字符串)

  • 地点monitor.py -> json.dumps()
  • 原因:数据库说:“我不认识什么列表字典,我只认识字(文本)。”
  • 形态str (字符串)
  • 样子
    '[{"index": "0", "temp": 45}, {"index": "1", "temp": 50}]'
    
    (注意最外面的单引号,它现在就是一句话,你没法直接读里面的 temp)

第3步:取货 (JSON 字符串)

  • 地点routes.py -> 从数据库查出来
  • 形态:依然是 str (字符串)
  • 样子:同上。

第4步:解析 (Python 列表)

  • 地点routes.py -> json.loads()
  • 原因:我们要把数据发给前端,得先把它变回“活”的数据结构,方便处理。
  • 形态:变回了 List[Dict]

第5步:发货 (JSON 响应)

  • 地点:FastAPI 自动处理
  • 形态:HTTP 响应体
  • 样子:浏览器看到的 JSON 格式。

第三章:Web 框架 FastAPI

3.1 为什么要有 Router?

比喻:公司架构

  • app = FastAPI()

    • 这是 CEO (老板)
    • 他坐在 main.py 办公室里。
    • 他负责公司开门(启动服务)、关门(停止服务)。
  • router = APIRouter()

    • 这是 部门经理
    • 他坐在 routes.py 办公室里。
    • 他负责具体的业务(比如“监控数据查询”这个部门)。
    • 他手下有很多员工(具体的接口函数,比如 get_current_metrics)。

为什么要分? 如果公司只有 3 个人,老板可以直接管。 但如果公司有 100 个业务(100 个接口),全让老板一个人管(全写在 main.py 里),老板会累死,文件会乱成一锅粥。 所以我们要把业务分给经理(Router),最后老板只要在 main.py 里说一句:“把监控部门经理叫来汇报工作 (app.include_router)” 就行了。


第四章:数据库设计(Repository 模式)

4.1 什么是 Repository?

比喻:图书管理员

  • 数据库:是一个巨大的、复杂的图书馆,书架乱七八糟。
  • 业务代码 (Service/API):是借书的人。如果不懂图书分类,进去就懵了。
  • Repository:就是那个专业的图书管理员

工作流程

  1. 你(API)管理员(Repository) 说:“帮我找那本叫《最新监控数据》的书。” (repo.get_one(...))
  2. 管理员 转身钻进图书馆,熟练地翻箱倒柜(执行 SQL 语句 SELECT * FROM ...)。
  3. 管理员 拿着书出来交给你。

好处: 你不需要知道书架在哪,也不需要知道怎么查 SQL,你只要会指挥管理员就行了。

4.2 为什么 Service 里是 self.repo,API 里是 get_repo()

  • Service (监控服务)

    • 它是一个 长工,住在公司里,24小时干活。
    • 所以它入职那一天(__init__),公司就发给它一套工具(self.repo),它一直挂在腰上,随时用。
  • API (接口)

    • 它是一个 临时工(按次计费)。
    • 只有当用户发请求来的时候,它才来上班。
    • 所以它每次来上班,都要先去仓库领一套工具(get_repo()),干完这一单活,工具就交回去(销毁),人也下班了。

第五章:异步编程 (Async/Await)

这是 Python 里比较难理解的一个点,我用最俗的例子给您讲。

场景:做饭

  • 任务 A:煮饭(需要 30 分钟,但只需要把米放进电饭煲,按下开关,然后就可以不管了)。
  • 任务 B:炒菜(需要一直站在锅边翻炒)。

同步编程 (Sync) —— 也就是普通写法

  1. 先把米放进电饭煲。
  2. 傻站在电饭煲面前等 30 分钟,直到饭熟了。
  3. 再去炒菜。 (效率极低,客人饿死了)

异步编程 (Async) —— async/await

  1. 先把米放进电饭煲。
  2. 按下开关,await (等待) 电饭煲自己工作。
  3. 立刻转身去炒菜(利用等待的时间干别的事)。
  4. 等电饭煲“叮”的一声(回调),再去盛饭。

在代码里

  • 读数据库、连 SSH 就像是“煮饭”。它是耗时的,但不需要 CPU 一直盯着。
  • 所以我们用 await,意思是:“你去连数据库吧,我去处理别的请求了,等你连好了告诉我一声。”
  • 这就是为什么用异步能让服务器同时处理成千上万个请求的原因。