<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Python 专题：从标准库到生产级工程 on PlumePHP</title><link>https://plumephp.com/posts/python/</link><description>Recent content in Python 专题：从标准库到生产级工程 on PlumePHP</description><generator>Hugo</generator><language>zh-CN</language><lastBuildDate>Mon, 28 Sep 2026 15:00:00 +0800</lastBuildDate><atom:link href="https://plumephp.com/posts/python/index.xml" rel="self" type="application/rss+xml"/><item><title>Python 微服务架构：从单体拆分到服务治理</title><link>https://plumephp.com/python-microservices-architecture/</link><pubDate>Mon, 28 Sep 2026 15:00:00 +0800</pubDate><guid>https://plumephp.com/python-microservices-architecture/</guid><description>&lt;blockquote&gt;
&lt;p&gt;微服务是架构演进的工具，不是目的。本文从「该不该拆」讲起，到 Python 微服务的技术栈落地，给出务实的拆分与治理方案。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="目录"&gt;目录&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="#1-%E5%8D%95%E4%BD%93-vs-%E5%BE%AE%E6%9C%8D%E5%8A%A1%E5%86%B3%E7%AD%96%E6%A1%86%E6%9E%B6"&gt;单体 vs 微服务：决策框架&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#2-%E6%9C%8D%E5%8A%A1%E6%8B%86%E5%88%86%E5%8E%9F%E5%88%99"&gt;服务拆分原则&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#3-fastapi-%E6%9C%8D%E5%8A%A1%E9%AA%A8%E6%9E%B6"&gt;FastAPI 服务骨架&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#4-%E6%9C%8D%E5%8A%A1%E9%97%B4%E9%80%9A%E4%BF%A1http-%E4%B8%8E-grpc"&gt;服务间通信：HTTP 与 gRPC&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#5-%E6%B6%88%E6%81%AF%E9%A9%B1%E5%8A%A8rabbitmq-%E4%B8%8E-kafka"&gt;消息驱动：RabbitMQ 与 Kafka&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#6-%E6%9C%8D%E5%8A%A1%E5%8F%91%E7%8E%B0%E4%B8%8E%E7%BD%91%E5%85%B3"&gt;服务发现与网关&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#7-%E9%85%8D%E7%BD%AE%E7%AE%A1%E7%90%86"&gt;配置管理&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#8-%E5%8F%AF%E8%A7%82%E6%B5%8B%E6%80%A7%E4%B8%89%E4%BB%B6%E5%A5%97"&gt;可观测性三件套&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#9-%E9%83%A8%E7%BD%B2%E4%B8%8E-cicd"&gt;部署与 CI/CD&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#10-%E6%BC%94%E8%BF%9B%E5%BC%8F%E6%8B%86%E5%88%86%E4%B8%8E%E9%80%9F%E6%9F%A5%E8%A1%A8"&gt;演进式拆分与速查表&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="1-单体-vs-微服务决策框架"&gt;1. 单体 vs 微服务：决策框架&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;维度&lt;/th&gt;
					&lt;th&gt;单体&lt;/th&gt;
					&lt;th&gt;微服务&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;团队规模&lt;/td&gt;
					&lt;td&gt;小团队&lt;/td&gt;
					&lt;td&gt;多团队独立交付&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;部署频率&lt;/td&gt;
					&lt;td&gt;一起部署&lt;/td&gt;
					&lt;td&gt;独立部署&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;故障隔离&lt;/td&gt;
					&lt;td&gt;全挂&lt;/td&gt;
					&lt;td&gt;局部降级&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;调用开销&lt;/td&gt;
					&lt;td&gt;进程内&lt;/td&gt;
					&lt;td&gt;网络 + 序列化&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;运维复杂度&lt;/td&gt;
					&lt;td&gt;低&lt;/td&gt;
					&lt;td&gt;高&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;调试&lt;/td&gt;
					&lt;td&gt;简单&lt;/td&gt;
					&lt;td&gt;跨服务追踪&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;决策判断&lt;/strong&gt;：没有 2+ 独立团队、没有独立扩缩容需求，就别上微服务。&lt;strong&gt;先做好模块化单体&lt;/strong&gt;。&lt;/p&gt;</description></item><item><title>Python 网络爬虫与自动化：从 requests 到 Playwright</title><link>https://plumephp.com/python-web-scraping-automation/</link><pubDate>Mon, 28 Sep 2026 14:00:00 +0800</pubDate><guid>https://plumephp.com/python-web-scraping-automation/</guid><description>&lt;blockquote&gt;
&lt;p&gt;网络爬虫是从公开网页采集数据的自动化技术。本文覆盖从单页请求到分布式爬虫、从静态页面到浏览器自动化的完整工具箱，并强调&lt;strong&gt;合规边界&lt;/strong&gt;。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="目录"&gt;目录&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="#1-%E7%88%AC%E8%99%AB%E7%9A%84%E5%90%88%E8%A7%84%E8%BE%B9%E7%95%8C"&gt;爬虫的合规边界&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#2-http-%E8%AF%B7%E6%B1%82requests-%E4%B8%8E-httpx"&gt;HTTP 请求：requests 与 httpx&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#3-%E8%A7%A3%E6%9E%90-htmlbeautifulsoup-%E4%B8%8E-lxml"&gt;解析 HTML：BeautifulSoup 与 lxml&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#4-xpath-%E4%B8%8E-css-%E9%80%89%E6%8B%A9%E5%99%A8"&gt;XPath 与 CSS 选择器&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#5-json-api-%E4%B8%8E%E5%BC%82%E6%AD%A5%E6%8A%93%E5%8F%96"&gt;JSON API 与异步抓取&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#6-scrapy-%E6%A1%86%E6%9E%B6"&gt;Scrapy 框架&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#7-playwright-%E6%B5%8F%E8%A7%88%E5%99%A8%E8%87%AA%E5%8A%A8%E5%8C%96"&gt;Playwright 浏览器自动化&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#8-%E5%8F%8D%E7%88%AC%E5%BA%94%E5%AF%B9%E4%B8%8E%E9%99%90%E9%80%9F"&gt;反爬应对与限速&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#9-%E6%95%B0%E6%8D%AE%E6%B8%85%E6%B4%97%E4%B8%8E%E5%AD%98%E5%82%A8"&gt;数据清洗与存储&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#10-%E9%80%9F%E6%9F%A5%E8%A1%A8%E4%B8%8E%E6%9C%80%E4%BD%B3%E5%AE%9E%E8%B7%B5"&gt;速查表与最佳实践&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="1-爬虫的合规边界"&gt;1. 爬虫的合规边界&lt;/h2&gt;
&lt;p&gt;在动手之前，先确认边界：&lt;/p&gt;</description></item><item><title>Python 库与 API 设计：从包结构到向后兼容</title><link>https://plumephp.com/python-api-library-design/</link><pubDate>Mon, 28 Sep 2026 13:00:00 +0800</pubDate><guid>https://plumephp.com/python-api-library-design/</guid><description>&lt;blockquote&gt;
&lt;p&gt;写一个「能跑」的脚本容易，写一个「好用」的库难。本文从 Python 库作者视角，拆解公开 API 面设计、兼容性保障与文档工程的完整方法论。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="目录"&gt;目录&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="#1-%E5%BA%93-vs-%E5%BA%94%E7%94%A8%E8%AE%BE%E8%AE%A1%E7%9B%AE%E6%A0%87%E5%B7%AE%E5%BC%82"&gt;库 vs 应用：设计目标差异&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#2-%E5%8C%85%E7%BB%93%E6%9E%84%E4%B8%8E%E6%A8%A1%E5%9D%97%E5%88%92%E5%88%86"&gt;包结构与模块划分&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#3-%E5%85%AC%E5%BC%80-api-%E9%9D%A2%E8%AE%BE%E8%AE%A1"&gt;公开 API 面设计&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#4-%E7%B1%BB%E5%9E%8B%E6%A0%87%E6%B3%A8%E4%B8%8E-protocol"&gt;类型标注与 Protocol&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#5-%E8%AF%AD%E4%B9%89%E5%8C%96%E7%89%88%E6%9C%AC%E4%B8%8E%E5%85%BC%E5%AE%B9%E6%80%A7"&gt;语义化版本与兼容性&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#6-%E5%90%91%E5%90%8E%E5%85%BC%E5%AE%B9%E7%AD%96%E7%95%A5"&gt;向后兼容策略&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#7-%E6%96%87%E6%A1%A3%E5%B7%A5%E7%A8%8B"&gt;文档工程&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#8-%E9%94%99%E8%AF%AF%E8%AE%BE%E8%AE%A1"&gt;错误设计&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#9-%E5%8F%91%E5%B8%83%E4%B8%8E%E7%A4%BE%E5%8C%BA%E6%B2%BB%E7%90%86"&gt;发布与社区治理&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#10-%E6%A1%88%E4%BE%8B%E6%8B%86%E8%A7%A3%E4%B8%8E%E9%80%9F%E6%9F%A5%E8%A1%A8"&gt;案例拆解与速查表&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="1-库-vs-应用设计目标差异"&gt;1. 库 vs 应用：设计目标差异&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;维度&lt;/th&gt;
					&lt;th&gt;应用&lt;/th&gt;
					&lt;th&gt;库&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;使用者&lt;/td&gt;
					&lt;td&gt;你（可控）&lt;/td&gt;
					&lt;td&gt;陌生用户（不可控）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;变更&lt;/td&gt;
					&lt;td&gt;随意改&lt;/td&gt;
					&lt;td&gt;必须兼容&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;日志&lt;/td&gt;
					&lt;td&gt;随便打&lt;/td&gt;
					&lt;td&gt;用 &lt;code&gt;logger = logging.getLogger(__name__)&lt;/code&gt; 但要克制&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;依赖&lt;/td&gt;
					&lt;td&gt;随意&lt;/td&gt;
					&lt;td&gt;尽量少，避免依赖地狱&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;错误&lt;/td&gt;
					&lt;td&gt;可崩溃&lt;/td&gt;
					&lt;td&gt;抛明确异常&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;接口&lt;/td&gt;
					&lt;td&gt;内部实现&lt;/td&gt;
					&lt;td&gt;长期契约&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;第一原则&lt;/strong&gt;：库作者要「克制」。每个新增功能都是未来要维护的契约。&lt;/p&gt;</description></item><item><title>Python C 扩展与 FFI：ctypes、cffi、Cython 与 PyO3</title><link>https://plumephp.com/python-c-extensions-ffi/</link><pubDate>Mon, 28 Sep 2026 12:00:00 +0800</pubDate><guid>https://plumephp.com/python-c-extensions-ffi/</guid><description>&lt;blockquote&gt;
&lt;p&gt;当纯 Python 性能不够时，C 扩展是最直接的出路。本文覆盖四种主流方案（ctypes / cffi / Cython / PyO3），从快速调用到深度编译逐层进阶。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="目录"&gt;目录&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="#1-%E4%B8%BA%E4%BB%80%E4%B9%88%E8%A6%81%E7%94%A8-c-%E6%89%A9%E5%B1%95"&gt;为什么要用 C 扩展&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#2-ctypes-%E8%B0%83%E7%94%A8%E5%8A%A8%E6%80%81%E5%BA%93"&gt;ctypes 调用动态库&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#3-ctypes-%E9%AB%98%E7%BA%A7%E7%BB%93%E6%9E%84%E4%BD%93%E4%B8%8E%E5%9B%9E%E8%B0%83"&gt;ctypes 高级：结构体与回调&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#4-cffi-%E5%AE%89%E5%85%A8%E7%BB%91%E5%AE%9A"&gt;cffi 安全绑定&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#5-cython-%E7%BC%96%E8%AF%91%E5%8A%A0%E9%80%9F"&gt;Cython 编译加速&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#6-cpython-c-api-%E5%85%A5%E9%97%A8"&gt;CPython C API 入门&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#7-pyo3%E7%94%A8-rust-%E5%86%99%E6%89%A9%E5%B1%95"&gt;PyO3：用 Rust 写扩展&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#8-gil-%E9%87%8A%E6%94%BE%E4%B8%8E%E5%B9%B6%E8%A1%8C"&gt;GIL 释放与并行&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#9-%E6%9E%84%E5%BB%BA%E4%B8%8E%E5%88%86%E5%8F%91"&gt;构建与分发&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#10-%E9%80%9F%E6%9F%A5%E8%A1%A8%E4%B8%8E%E9%80%89%E5%9E%8B%E5%86%B3%E7%AD%96"&gt;速查表与选型决策&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="1-为什么要用-c-扩展"&gt;1. 为什么要用 C 扩展&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;场景&lt;/th&gt;
					&lt;th&gt;方案&lt;/th&gt;
					&lt;th&gt;加速比&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;调用现成 C 库&lt;/td&gt;
					&lt;td&gt;ctypes / cffi&lt;/td&gt;
					&lt;td&gt;函数级&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;计算热点（循环）&lt;/td&gt;
					&lt;td&gt;Cython&lt;/td&gt;
					&lt;td&gt;10-100x&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;数字计算&lt;/td&gt;
					&lt;td&gt;NumPy 向量化&lt;/td&gt;
					&lt;td&gt;100x+（无需手写）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;系统级 / 高性能&lt;/td&gt;
					&lt;td&gt;PyO3 (Rust)&lt;/td&gt;
					&lt;td&gt;编译语言级别&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;判断顺序&lt;/strong&gt;：NumPy/Pandas 能否解决？→ 用已有的 &lt;code&gt;C&lt;/code&gt; 扩展库？→ 才考虑自己写。&lt;/p&gt;</description></item><item><title>Python 调试与日志工程：从 print 到可观测性</title><link>https://plumephp.com/python-debugging-logging/</link><pubDate>Mon, 28 Sep 2026 11:00:00 +0800</pubDate><guid>https://plumephp.com/python-debugging-logging/</guid><description>&lt;blockquote&gt;
&lt;p&gt;调试不是「出 bug 才做的事」，而是理解程序行为的基本方法。本文从最快的 &lt;code&gt;print&lt;/code&gt; 技巧讲到生产级结构化日志，帮你建立一套完整的调试与可观测性工具箱。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="目录"&gt;目录&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="#1-print-%E8%B0%83%E8%AF%95%E7%9A%84%E8%89%BA%E6%9C%AF"&gt;print 调试的艺术&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#2-pdb-%E4%BA%A4%E4%BA%92%E5%BC%8F%E8%B0%83%E8%AF%95"&gt;pdb 交互式调试&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#3-%E5%BC%82%E5%B8%B8%E4%B8%8E-traceback-%E6%B7%B1%E5%85%A5"&gt;异常与 traceback 深入&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#4-logging-%E6%9E%B6%E6%9E%84"&gt;logging 架构&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#5-%E7%BB%93%E6%9E%84%E5%8C%96%E6%97%A5%E5%BF%97-structlog"&gt;结构化日志 structlog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#6-%E6%97%A5%E5%BF%97%E9%85%8D%E7%BD%AE%E5%AE%9E%E6%88%98"&gt;日志配置实战&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#7-%E6%80%A7%E8%83%BD%E5%89%96%E6%9E%90-py-spy-%E4%B8%8E-cprofile"&gt;性能剖析 py-spy 与 cProfile&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#8-%E5%86%85%E5%AD%98%E6%B3%84%E6%BC%8F%E5%AE%9A%E4%BD%8D"&gt;内存泄漏定位&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#9-%E7%94%9F%E4%BA%A7%E5%8F%AF%E8%A7%82%E6%B5%8B%E6%80%A7%E9%9B%86%E6%88%90"&gt;生产可观测性集成&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#10-%E9%80%9F%E6%9F%A5%E8%A1%A8%E4%B8%8E%E6%9C%80%E4%BD%B3%E5%AE%9E%E8%B7%B5"&gt;速查表与最佳实践&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="1-print-调试的艺术"&gt;1. print 调试的艺术&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;print&lt;/code&gt; 是最快的调试手段，但要 print 得聪明：&lt;/p&gt;</description></item><item><title>Python 设计模式与 SOLID：从经典模式到 Pythonic 简化</title><link>https://plumephp.com/python-design-patterns/</link><pubDate>Mon, 28 Sep 2026 10:00:00 +0800</pubDate><guid>https://plumephp.com/python-design-patterns/</guid><description>&lt;blockquote&gt;
&lt;p&gt;本文是 &lt;a href="https://plumephp.com/posts/python/python-metaprogramming"&gt;Python 元编程与动态特性&lt;/a&gt; 的姊妹篇，聚焦面向对象设计的「套路」层——如何组织类与对象，让代码可扩展、可测试、可维护。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="目录"&gt;目录&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="#1-%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E5%9C%A8-python-%E4%B8%AD%E7%9A%84%E4%BD%8D%E7%BD%AE"&gt;设计模式在 Python 中的位置&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#2-solid-%E4%BA%94%E5%8E%9F%E5%88%99"&gt;SOLID 五原则&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#3-%E5%88%9B%E5%BB%BA%E5%9E%8B%E6%A8%A1%E5%BC%8F"&gt;创建型模式&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#4-%E7%BB%93%E6%9E%84%E5%9E%8B%E6%A8%A1%E5%BC%8F"&gt;结构型模式&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#5-%E8%A1%8C%E4%B8%BA%E5%9E%8B%E6%A8%A1%E5%BC%8F"&gt;行为型模式&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#6-pythonic-%E6%9B%BF%E4%BB%A3%E7%94%A8%E8%AF%AD%E8%A8%80%E7%89%B9%E6%80%A7%E7%AE%80%E5%8C%96%E7%BB%8F%E5%85%B8%E6%A8%A1%E5%BC%8F"&gt;Pythonic 替代：用语言特性简化经典模式&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#7-%E5%87%BD%E6%95%B0%E5%BC%8F%E6%A8%A1%E5%BC%8F"&gt;函数式模式&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#8-%E6%A8%A1%E5%BC%8F%E9%80%89%E5%9E%8B%E4%B8%8E%E8%BF%87%E5%BA%A6%E8%AE%BE%E8%AE%A1"&gt;模式选型与过度设计&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#9-%E5%AE%9E%E6%88%98%E4%B8%80%E4%B8%AA%E5%8F%AF%E7%BB%B4%E6%8A%A4%E7%9A%84%E6%94%AF%E4%BB%98%E7%B3%BB%E7%BB%9F"&gt;实战：一个可维护的支付系统&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#10-%E9%80%9F%E6%9F%A5%E8%A1%A8%E4%B8%8E%E6%9C%80%E4%BD%B3%E5%AE%9E%E8%B7%B5"&gt;速查表与最佳实践&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="1-设计模式在-python-中的位置"&gt;1. 设计模式在 Python 中的位置&lt;/h2&gt;
&lt;p&gt;设计模式是解决特定场景问题的&lt;strong&gt;经过验证的模板&lt;/strong&gt;。Python 因动态特性、一等函数和鸭子类型，很多经典模式「方言」比 Go 书里的 C++/Java 版本&lt;strong&gt;更简洁&lt;/strong&gt;。&lt;/p&gt;</description></item><item><title>Python 高级异步编程：Trio 结构化并发与 AnyIO 兼容层</title><link>https://plumephp.com/python-async-advanced/</link><pubDate>Tue, 18 Aug 2026 12:00:00 +0800</pubDate><guid>https://plumephp.com/python-async-advanced/</guid><description>&lt;h2 id="1-asyncio-的局限与痛点"&gt;1. asyncio 的局限与痛点&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;asyncio&lt;/code&gt; 是 Python 标准库中的异步编程框架，自 Python 3.4 引入以来已经发展成熟。然而，在生产环境和高并发场景下，asyncio 暴露出一系列设计上的缺陷：&lt;/p&gt;</description></item><item><title>Python 数据工程与 ETL 管道实战</title><link>https://plumephp.com/python-data-engineering-etl/</link><pubDate>Tue, 18 Aug 2026 11:00:00 +0800</pubDate><guid>https://plumephp.com/python-data-engineering-etl/</guid><description>&lt;h2 id="1-etl-基础抽取转换加载"&gt;1. ETL 基础：抽取、转换、加载&lt;/h2&gt;
&lt;p&gt;ETL（Extract-Transform-Load）是数据工程中最经典也最核心的数据处理模式。它的本质使命是将分散在各处的原始数据，经过系统化清洗与重组后，加载到目标存储中，使其能够被数据分析、机器学习模型或者业务报表直接消费。任何数据驱动型组织的底层基础设施，几乎都离不开一套稳定、可扩展的 ETL 管道。理解每个阶段的设计原则和常见陷阱，是构建可维护数据架构的第一步。&lt;/p&gt;</description></item><item><title>Python 元编程与动态特性深度解析</title><link>https://plumephp.com/python-metaprogramming/</link><pubDate>Tue, 18 Aug 2026 10:00:00 +0800</pubDate><guid>https://plumephp.com/python-metaprogramming/</guid><description>&lt;h2 id="1-动态属性访问__getattr____getattribute____setattr__"&gt;1. 动态属性访问：&lt;code&gt;__getattr__&lt;/code&gt;、&lt;code&gt;__getattribute__&lt;/code&gt;、&lt;code&gt;__setattr__&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;Python 的属性访问机制是元编程的基石。与普通语言不同，Python 中的每一次属性查找都可以被自定义拦截和重定向。理解这三个魔术方法的调用顺序和差异，是掌握动态特性的第一步。它们在访问控制、属性代理、延迟加载等场景中发挥着至关重要的作用。&lt;/p&gt;</description></item><item><title>Python + LLM 实战：OpenAI API 集成与 Agent 开发</title><link>https://plumephp.com/python-llm-openai-integration/</link><pubDate>Sat, 15 Aug 2026 10:00:00 +0800</pubDate><guid>https://plumephp.com/python-llm-openai-integration/</guid><description>&lt;h2 id="1-openai-api-基础"&gt;1. OpenAI API 基础&lt;/h2&gt;
&lt;h3 id="11-安装与配置"&gt;1.1 安装与配置&lt;/h3&gt;
&lt;p&gt;在使用 OpenAI API 之前，需要先安装官方 SDK 并配置 API Key。推荐使用 &lt;code&gt;python-dotenv&lt;/code&gt; 管理环境变量，避免将密钥硬编码到代码中。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pip install openai python-dotenv
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;os&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OpenAI&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;dotenv&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;load_dotenv&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;load_dotenv&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;OpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;OPENAI_API_KEY&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 基础调用&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chat&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;completions&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;gpt-4o&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;role&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;system&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;content&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;你是一个 helpful 助手&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;role&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;user&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;content&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;解释 Python 的 GIL 是什么&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;temperature&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;max_tokens&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;choices&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;temperature&lt;/code&gt; 参数控制输出的随机性，取值范围 0 到 2。值为 0 时输出最确定性，适合代码生成和结构化数据提取；值为 0.7 到 1 时适合创意写作和头脑风暴。&lt;code&gt;max_tokens&lt;/code&gt; 限制单次响应的最大 token 数，可防止意外产生超长输出导致费用激增。&lt;/p&gt;</description></item><item><title>Python 异步任务队列：Celery + Redis/RabbitMQ 实战</title><link>https://plumephp.com/python-celery-task-queue/</link><pubDate>Sat, 15 Aug 2026 10:00:00 +0800</pubDate><guid>https://plumephp.com/python-celery-task-queue/</guid><description>&lt;h2 id="1-celery-架构"&gt;1. Celery 架构&lt;/h2&gt;
&lt;p&gt;Celery 是典型的分布式任务队列系统，采用生产者-消费者模型，将耗时的后台操作与主请求流程解耦。其架构由四个核心角色组成：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Application
 ├── Producer（Flask/Django/FastAPI）──→ 发送任务
 │
 ├── Broker（Redis / RabbitMQ）───────→ 任务队列存储
 │
 ├── Worker（多进程/多线程）────────→ 消费并执行任务
 │
 └── Backend（Redis / Database）────→ 存储任务结果
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Producer 负责通过 &lt;code&gt;delay()&lt;/code&gt; 或 &lt;code&gt;apply_async()&lt;/code&gt; 将任务序列化后投递到 Broker。Broker 作为消息中间件持久化任务，Worker 从 Broker 拉取任务并执行，最终结果写入 Backend，供客户端异步查询。该架构天然支持水平扩展：Worker 可以独立部署在多台机器上，通过统一的 Broker 实现负载均衡。&lt;/p&gt;</description></item><item><title>Python 数据分析：Pandas 与 Polars 实战</title><link>https://plumephp.com/python-pandas-data-analysis/</link><pubDate>Sat, 15 Aug 2026 10:00:00 +0800</pubDate><guid>https://plumephp.com/python-pandas-data-analysis/</guid><description>&lt;h2 id="1-pandas-核心操作"&gt;1. Pandas 核心操作&lt;/h2&gt;
&lt;h3 id="11-dataframe-基础"&gt;1.1 DataFrame 基础&lt;/h3&gt;
&lt;p&gt;Pandas 的 DataFrame 本质上是一个带有标签的二维表格结构，其底层由多个一维的 Series 对象按列组合而成。每个 Series 共享同一组行索引（Index），这使得按列进行向量化运算和按行进行切片查询都变得高效且直观。理解 DataFrame 的内存布局对后续的性能调优至关重要：默认情况下，各列在内存中是连续存储的，因此列级别的操作远比逐行循环要快得多。&lt;/p&gt;</description></item><item><title>Python 数据库实战：SQLite、PostgreSQL、SQLAlchemy 与 ORM 完全指南</title><link>https://plumephp.com/python-database-orm/</link><pubDate>Thu, 13 Aug 2026 16:00:00 +0800</pubDate><guid>https://plumephp.com/python-database-orm/</guid><description>&lt;blockquote&gt;
&lt;p&gt;几乎所有 Python 应用都需要持久化数据。本文从 SQLite 起步，到 SQLAlchemy ORM，再到异步数据库访问，给你一个完整的数据库技术栈。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="目录"&gt;目录&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="#1-%E6%95%B0%E6%8D%AE%E5%BA%93%E9%80%89%E5%9E%8B%E6%8C%87%E5%8D%97"&gt;数据库选型指南&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#2-sqlite%E9%9B%B6%E9%85%8D%E7%BD%AE%E6%95%B0%E6%8D%AE%E5%BA%93"&gt;SQLite：零配置数据库&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#3-postgresql-%E4%B8%8E-psycopg2"&gt;PostgreSQL 与 psycopg2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#4-sqlalchemy-orm-%E6%A0%B8%E5%BF%83"&gt;SQLAlchemy ORM 核心&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#5-%E5%85%B3%E7%B3%BB%E4%B8%8E%E6%9F%A5%E8%AF%A2"&gt;关系与查询&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#6-%E5%BC%82%E6%AD%A5%E6%95%B0%E6%8D%AE%E5%BA%93asyncpg"&gt;异步数据库：asyncpg&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#7-%E6%95%B0%E6%8D%AE%E5%BA%93%E8%BF%81%E7%A7%BBalembic"&gt;数据库迁移：Alembic&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#8-sqlalchemy-20-%E6%96%B0%E8%8C%83%E5%BC%8F"&gt;SQLAlchemy 2.0 新范式&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#9-%E8%BF%9E%E6%8E%A5%E6%B1%A0%E6%B7%B1%E5%BA%A6%E9%85%8D%E7%BD%AE"&gt;连接池深度配置&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#10-orm-%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96%E5%AE%9E%E6%88%98"&gt;ORM 性能优化实战&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#11-%E6%95%B0%E6%8D%AE%E5%BA%93%E4%BA%8B%E5%8A%A1%E9%9A%94%E7%A6%BB%E7%BA%A7%E5%88%AB%E4%B8%8E%E6%AD%BB%E9%94%81%E5%A4%84%E7%90%86"&gt;数据库事务隔离级别与死锁处理&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#12-%E6%B5%8B%E8%AF%95%E6%95%B0%E6%8D%AE%E5%BA%93%E7%AD%96%E7%95%A5"&gt;测试数据库策略&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#13-%E7%94%9F%E4%BA%A7%E7%8E%AF%E5%A2%83%E6%9C%80%E4%BD%B3%E5%AE%9E%E8%B7%B5"&gt;生产环境最佳实践&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="1-数据库选型指南"&gt;1. 数据库选型指南&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;数据库&lt;/th&gt;
					&lt;th&gt;适用场景&lt;/th&gt;
					&lt;th&gt;Python 驱动&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;SQLite&lt;/td&gt;
					&lt;td&gt;单机应用、测试、嵌入式&lt;/td&gt;
					&lt;td&gt;sqlite3（内置）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;PostgreSQL&lt;/td&gt;
					&lt;td&gt;生产应用、复杂查询&lt;/td&gt;
					&lt;td&gt;psycopg2, asyncpg&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;a href="https://plumephp.com/posts/database/"&gt;MySQL&lt;/a&gt;&lt;/td&gt;
					&lt;td&gt;Web 应用、LAMP 栈&lt;/td&gt;
					&lt;td&gt;PyMySQL, mysqlclient&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;a href="https://plumephp.com/posts/mongodb/"&gt;MongoDB&lt;/a&gt;&lt;/td&gt;
					&lt;td&gt;文档型数据&lt;/td&gt;
					&lt;td&gt;pymongo&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;a href="https://plumephp.com/posts/redis/"&gt;Redis&lt;/a&gt;&lt;/td&gt;
					&lt;td&gt;缓存、&lt;a href="https://plumephp.com/posts/kafka/"&gt;消息队列&lt;/a&gt;&lt;/td&gt;
					&lt;td&gt;redis-py&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="2-sqlite零配置数据库"&gt;2. SQLite：零配置数据库&lt;/h2&gt;
&lt;h3 id="21-基础-crud"&gt;2.1 基础 CRUD&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;sqlite3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;pathlib&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;DB_PATH&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;app.db&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;init_db&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;sqlite3&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DB_PATH&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; CREATE TABLE IF NOT EXISTS users (
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; id INTEGER PRIMARY KEY AUTOINCREMENT,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; name TEXT NOT NULL,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; email TEXT UNIQUE,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; )
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add_user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;sqlite3&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DB_PATH&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;INSERT INTO users (name, email) VALUES (?, ?)&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_users&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;sqlite3&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DB_PATH&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;row_factory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sqlite3&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Row&lt;/span&gt; &lt;span class="c1"&gt;# 返回字典式结果&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;SELECT * FROM users&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fetchall&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 使用&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;init_db&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;add_user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Alice&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;alice@example.com&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;get_users&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="22-sqlite-高级特性"&gt;2.2 SQLite 高级特性&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 事务控制&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;sqlite3&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DB_PATH&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;INSERT INTO users (name) VALUES (?)&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Bob&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;INSERT INTO invalid_table ...&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# 会失败&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;sqlite3&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rollback&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 返回字典结果&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;row_factory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;col&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;col&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;enumerate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# FTS5 全文搜索（需要编译时启用）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;CREATE VIRTUAL TABLE docs USING fts5(title, content)&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="3-postgresql-与-psycopg2"&gt;3. PostgreSQL 与 psycopg2&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# pip install psycopg2-binary&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;psycopg2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;psycopg2.extras&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;RealDictCursor&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;conn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;psycopg2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;localhost&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;database&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;mydb&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;myuser&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;mypass&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cursor_factory&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;RealDictCursor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;cur&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;cur&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;SELECT * FROM users WHERE age &amp;gt; &lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;,))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;cur&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fetchall&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="4-sqlalchemy-orm-核心"&gt;4. SQLAlchemy ORM 核心&lt;/h2&gt;
&lt;h3 id="41-模型定义"&gt;4.1 模型定义&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# pip install sqlalchemy&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;sqlalchemy&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;create_engine&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ForeignKey&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;sqlalchemy.orm&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;declarative_base&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;relationship&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sessionmaker&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;datetime&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Base&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;declarative_base&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Base&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;__tablename__&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;users&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;primary_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;nullable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;unique&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;utcnow&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;posts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;relationship&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Post&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;back_populates&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;author&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Base&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;__tablename__&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;posts&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;primary_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;nullable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;author_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ForeignKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;users.id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;author&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;relationship&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;User&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;back_populates&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;posts&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 创建表&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;engine&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;create_engine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;sqlite:///app.db&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;echo&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Base&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create_all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Session&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sessionmaker&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bind&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="42-crud-操作"&gt;4.2 CRUD 操作&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 创建&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;Session&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Alice&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;alice@example.com&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# 自动获取自增 ID&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 查询&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;Session&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 主键查询&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 条件查询&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;like&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;A%&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;all&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 分页&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;offset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;all&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 更新&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;Session&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;New Name&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 删除&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;Session&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="5-关系与查询"&gt;5. 关系与查询&lt;/h2&gt;
&lt;h3 id="51-关联查询"&gt;5.1 关联查询&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 一对多：用户 - 文章&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;Session&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;post&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 预加载（避免 N+1 查询）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;sqlalchemy.orm&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;joinedload&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;joinedload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;all&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 聚合查询&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;sqlalchemy&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;func&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Post&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;post_count&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;group_by&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;all&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="6-异步数据库asyncpg"&gt;6. 异步数据库：asyncpg&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# pip install asyncpg&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;asyncpg&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;asyncio&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;conn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;asyncpg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;postgresql://user:pass@localhost/db&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 查询&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;rows&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;SELECT * FROM users WHERE age &amp;gt; $1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 事务&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;transaction&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;INSERT INTO users (name) VALUES ($1)&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Bob&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="sqlalchemy-异步版本"&gt;SQLAlchemy 异步版本&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;sqlalchemy.ext.asyncio&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;create_async_engine&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;AsyncSession&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;sqlalchemy.orm&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;sessionmaker&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;async_engine&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;create_async_engine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;postgresql+asyncpg://user:pass@localhost/db&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;AsyncSessionLocal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sessionmaker&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;async_engine&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;class_&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;AsyncSession&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_users&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;AsyncSessionLocal&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;scalars&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;all&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="7-数据库迁移alembic"&gt;7. 数据库迁移：Alembic&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 安装&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pip install alembic
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 初始化&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;alembic init migrations
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 修改 alembic.ini → sqlalchemy.url = postgresql://user:pass@localhost/db&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 修改 migrations/env.py → 导入你的 Base&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 生成迁移脚本&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;alembic revision --autogenerate -m &lt;span class="s2"&gt;&amp;#34;create users table&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 升级&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;alembic upgrade head
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 降级&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;alembic downgrade -1
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="8-sqlalchemy-20-新范式"&gt;8. SQLAlchemy 2.0 新范式&lt;/h2&gt;
&lt;p&gt;SQLAlchemy 2.0 是一次重大升级，彻底革新了声明式定义和查询风格。新版本要求使用 &lt;code&gt;mapped_column()&lt;/code&gt; 替代 &lt;code&gt;Column()&lt;/code&gt;，天然集成 Python 类型提示，让 IDE 自动补全和静态类型检查器（如 mypy）可以正确推断模型字段类型。这种方式解决了旧版 ORM 中类型系统与运行时行为分离的痛点，使得大型项目中的模型定义更加清晰、可维护。此外，查询语法全面转向函数式风格，&lt;code&gt;select()&lt;/code&gt;、&lt;code&gt;insert()&lt;/code&gt;、&lt;code&gt;update()&lt;/code&gt; 等显式构造取代了隐式的 &lt;code&gt;session.query()&lt;/code&gt; 链式调用，语义更加明确。&lt;/p&gt;</description></item><item><title>Python 网络编程：socket、HTTP 客户端与服务端开发完全指南</title><link>https://plumephp.com/python-network-programming/</link><pubDate>Thu, 13 Aug 2026 15:00:00 +0800</pubDate><guid>https://plumephp.com/python-network-programming/</guid><description>&lt;blockquote&gt;
&lt;p&gt;网络编程是连接程序与世界的桥梁。从底层的 socket 到高层的 HTTP 请求，本文带你掌握 Python 中网络通信的每个层次。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="目录"&gt;目录&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="#1-%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B%E5%B1%82%E6%AC%A1%E6%A6%82%E8%A7%88"&gt;网络编程层次概览&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#2-socket-%E5%9F%BA%E7%A1%80tcp-%E5%AE%A2%E6%88%B7%E7%AB%AF%E6%9C%8D%E5%8A%A1%E7%AB%AF"&gt;Socket 基础：TCP 客户端/服务端&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#3-udp-%E7%BC%96%E7%A8%8B%E6%97%A0%E8%BF%9E%E6%8E%A5%E9%80%9A%E4%BF%A1"&gt;UDP 编程：无连接通信&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#4-http-%E5%AE%A2%E6%88%B7%E7%AB%AFrequests-vs-urllib"&gt;HTTP 客户端：requests vs urllib&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#5-%E5%BC%82%E6%AD%A5-httpaiohttp"&gt;异步 HTTP：aiohttp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#6-%E7%94%A8-python-%E5%86%99-web-%E6%9C%8D%E5%8A%A1%E5%99%A8"&gt;用 Python 写 Web 服务器&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#7-websocket-%E5%AE%9E%E6%97%B6%E9%80%9A%E4%BF%A1"&gt;WebSocket 实时通信&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#8-%E7%BD%91%E7%BB%9C%E8%B0%83%E8%AF%95%E6%8A%80%E5%B7%A7"&gt;网络调试技巧&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="1-网络编程层次概览"&gt;1. 网络编程层次概览&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;应用层：HTTP、FTP、DNS
 │
传输层：TCP（可靠连接）、UDP（无连接）
 │
网络层：IP（寻址与路由）
 │
链路层：以太网、WiFi
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Python 可在每个层次编程：&lt;/p&gt;</description></item><item><title>Python 安全编程：输入验证、加密与常见漏洞防护</title><link>https://plumephp.com/python-security-best-practices/</link><pubDate>Thu, 13 Aug 2026 14:00:00 +0800</pubDate><guid>https://plumephp.com/python-security-best-practices/</guid><description>&lt;blockquote&gt;
&lt;p&gt;安全不是功能，而是所有功能的基础。本文覆盖 Python 开发中最常见的安全风险——从输入验证到密码存储，从 SQL 注入到反序列化攻击——并给出可直接使用的防御代码。&lt;/p&gt;</description></item><item><title>Python 模块与包管理：从 import 语句到私有仓库的完整指南</title><link>https://plumephp.com/python-modules-packages-import/</link><pubDate>Thu, 13 Aug 2026 13:00:00 +0800</pubDate><guid>https://plumephp.com/python-modules-packages-import/</guid><description>&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;import&lt;/code&gt; 是 Python 程序的第一行代码，也是出问题的重灾区。ModuleNotFoundError、循环导入、相对路径报错……本文从 Python 的导入系统原理讲起，帮你彻底解决这些问题。&lt;/p&gt;</description></item><item><title>Python 内存管理、垃圾回收与性能调优：写出内存友好的 Python 代码</title><link>https://plumephp.com/python-memory-gc-performance/</link><pubDate>Thu, 13 Aug 2026 12:00:00 +0800</pubDate><guid>https://plumephp.com/python-memory-gc-performance/</guid><description>&lt;blockquote&gt;
&lt;p&gt;Python 的内存管理是自动的，但&amp;quot;自动&amp;quot;不等于&amp;quot;高效&amp;quot;。理解引用计数和垃圾回收机制，学会使用 &lt;code&gt;__slots__&lt;/code&gt; 和对象池，掌握内存泄漏排查工具——这是从&amp;quot;会写 Python&amp;quot;到&amp;quot;写好 Python&amp;quot;的分水岭。&lt;/p&gt;</description></item><item><title>Python 文件 IO 与数据序列化：从 CSV 到 Parquet 的完整指南</title><link>https://plumephp.com/python-file-io-serialization/</link><pubDate>Thu, 13 Aug 2026 11:00:00 +0800</pubDate><guid>https://plumephp.com/python-file-io-serialization/</guid><description>&lt;blockquote&gt;
&lt;p&gt;无论是日志处理、数据导出还是配置管理，文件 IO 和序列化都是 Python 开发者每天面对的任务。本文覆盖从基础文本操作到高性能二进制格式的完整技术栈。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="目录"&gt;目录&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="#1-pathlib%E7%8E%B0%E4%BB%A3%E8%B7%AF%E5%BE%84%E6%93%8D%E4%BD%9C"&gt; pathlib：现代路径操作&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#2-%E6%96%87%E6%9C%AC%E6%96%87%E4%BB%B6%E8%AF%BB%E5%86%99"&gt; 文本文件读写&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#3-%E4%BA%8C%E8%BF%9B%E5%88%B6%E6%96%87%E4%BB%B6%E4%B8%8E%E5%86%85%E5%AD%98%E6%98%A0%E5%B0%84"&gt; 二进制文件与内存映射&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#4-csv-%E5%A4%84%E7%90%86"&gt; CSV 处理&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#5-json-%E5%BA%8F%E5%88%97%E5%8C%96"&gt; JSON 序列化&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#6-yaml-%E9%85%8D%E7%BD%AE"&gt; YAML 配置&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#7-picklepython-%E5%8E%9F%E7%94%9F%E5%BA%8F%E5%88%97%E5%8C%96"&gt; Pickle：Python 原生序列化&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#8-messagepack%E4%BA%8C%E8%BF%9B%E5%88%B6-json"&gt; MessagePack：二进制 JSON&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#9-parquet%E5%88%97%E5%BC%8F%E5%AD%98%E5%82%A8"&gt; Parquet：列式存储&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#10-%E5%A4%A7%E6%95%B0%E6%8D%AE%E5%88%86%E5%9D%97%E8%AF%BB%E5%8F%96"&gt; 大数据分块读取&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#11-%E7%BC%96%E7%A0%81%E5%A4%84%E7%90%86"&gt; 编码处理&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#12-%E5%BA%8F%E5%88%97%E5%8C%96%E6%A0%BC%E5%BC%8F%E9%80%89%E5%9E%8B%E9%80%9F%E6%9F%A5"&gt; 序列化格式选型速查&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#13-%E5%86%85%E5%AD%98%E6%96%87%E4%BB%B6%E4%B8%8E%E4%B8%B4%E6%97%B6%E6%96%87%E4%BB%B6"&gt; 内存文件与临时文件&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="1-pathlib现代路径操作"&gt;1. pathlib：现代路径操作&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;pathlib&lt;/code&gt; 是 Python 3.4+ 引入的面向对象路径库，已取代 &lt;code&gt;os.path&lt;/code&gt;：&lt;/p&gt;</description></item><item><title>Python 装饰器与上下文管理器：从语法糖到工程实践</title><link>https://plumephp.com/python-decorators-context-managers/</link><pubDate>Thu, 13 Aug 2026 10:00:00 +0800</pubDate><guid>https://plumephp.com/python-decorators-context-managers/</guid><description>&lt;blockquote&gt;
&lt;p&gt;装饰器和上下文管理器是 Python 的两大&amp;quot;魔法特性&amp;quot;。它们让代码更优雅、更易维护，但也常常让初学者困惑。本文把它们拆解为&amp;quot;可理解的积木&amp;quot;，让你不仅会用，还能自己写。&lt;/p&gt;</description></item><item><title>Python 内置数据结构完全指南：list、dict、set 与 collections 深度解析</title><link>https://plumephp.com/python-built-in-data-structures/</link><pubDate>Wed, 12 Aug 2026 19:00:00 +0800</pubDate><guid>https://plumephp.com/python-built-in-data-structures/</guid><description>&lt;blockquote&gt;
&lt;p&gt;写 Python 代码，80% 的时间在操作数据结构。本文不讲抽象理论，而是告诉你每种结构&lt;strong&gt;什么时候用、怎么用最快、有什么坑&lt;/strong&gt;。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="目录"&gt;目录&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="#1-%E6%80%BB%E8%A7%88%E9%80%89%E6%8B%A9%E6%AD%A3%E7%A1%AE%E7%9A%84%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84"&gt;总览：选择正确的数据结构&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#2-list%E5%8A%A8%E6%80%81%E6%95%B0%E7%BB%84%E7%9A%84%E5%88%A9%E4%B8%8E%E5%BC%8A"&gt;list：动态数组的利与弊&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#3-tuple%E4%B8%8D%E5%8F%AF%E5%8F%98%E5%BA%8F%E5%88%97%E7%9A%84%E5%A6%99%E7%94%A8"&gt;tuple：不可变序列的妙用&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#4-dict%E5%93%88%E5%B8%8C%E8%A1%A8%E7%9A%84%E5%B7%A5%E7%A8%8B%E5%AE%9E%E8%B7%B5"&gt;dict：哈希表的工程实践&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#5-set%E9%9B%86%E5%90%88%E8%BF%90%E7%AE%97%E4%B8%8E%E5%8E%BB%E9%87%8D"&gt;set：集合运算与去重&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#6-collections-%E6%A8%A1%E5%9D%97%E8%BF%9B%E9%98%B6"&gt;collections 模块进阶&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#7-%E6%97%B6%E9%97%B4%E5%A4%8D%E6%9D%82%E5%BA%A6%E9%80%9F%E6%9F%A5%E8%A1%A8"&gt;时间复杂度速查表&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#8-%E5%AE%9E%E6%88%98%E5%9C%BA%E6%99%AF%E9%80%89%E5%9E%8B%E5%86%B3%E7%AD%96"&gt;实战场景选型决策&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="1-总览选择正确的数据结构"&gt;1. 总览：选择正确的数据结构&lt;/h2&gt;
&lt;p&gt;Python 内置了丰富的数据结构，每种都有其&lt;strong&gt;最佳使用场景&lt;/strong&gt;：&lt;/p&gt;</description></item><item><title>Python GIL 深度解析：全局解释器锁对并发编程的影响与绕过策略</title><link>https://plumephp.com/python-de-gil-dui-bing-fa-bian-cheng-you-na-xie-ying-xiang/</link><pubDate>Wed, 12 Aug 2026 18:00:00 +0800</pubDate><guid>https://plumephp.com/python-de-gil-dui-bing-fa-bian-cheng-you-na-xie-ying-xiang/</guid><description>&lt;blockquote&gt;
&lt;p&gt;本文是 &lt;a href="https://plumephp.com/posts/python/python-concurrency-performance"&gt;Python 并发与性能深度指南&lt;/a&gt; 的配套专题，聚焦 GIL 这一 Python 并发编程中最常被误解的概念。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="目录"&gt;目录&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="#1-gil-%E6%98%AF%E4%BB%80%E4%B9%88"&gt;GIL 是什么&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#2-%E4%B8%BA%E4%BB%80%E4%B9%88-python-%E9%9C%80%E8%A6%81-gil"&gt;为什么 Python 需要 GIL&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#3-gil-%E5%AF%B9%E4%B8%8D%E5%90%8C%E7%B1%BB%E5%9E%8B%E4%BB%BB%E5%8A%A1%E7%9A%84%E5%BD%B1%E5%93%8D"&gt;GIL 对不同类型任务的影响&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#4-%E7%BB%95%E8%BF%87-gil-%E7%9A%84%E7%AD%96%E7%95%A5"&gt;绕过 GIL 的策略&lt;/a&gt;&lt;br&gt;
4.5. &lt;a href="#45-concurrentfutures%E9%AB%98%E7%BA%A7%E5%B9%B6%E5%8F%91%E6%8A%BD%E8%B1%A1"&gt;&lt;code&gt;concurrent.futures&lt;/code&gt;：高级并发抽象&lt;/a&gt;&lt;br&gt;
4.6. &lt;a href="#46-cython-%E4%B8%8E-nogil-%E9%87%8A%E6%94%BE-gil"&gt;Cython 与 nogil 释放 GIL&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#5-python-313-%E7%9A%84-nogil-%E5%AE%9E%E9%AA%8C"&gt;Python 3.13 的 nogil 实验&lt;/a&gt;&lt;br&gt;
5.1. &lt;a href="#51-%E6%80%A7%E8%83%BD%E5%9F%BA%E5%87%86%E5%AF%B9%E6%AF%94"&gt;性能基准对比&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#6-%E5%B8%B8%E8%A7%81%E8%AF%AF%E5%8C%BA"&gt;常见误区&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="1-gil-是什么"&gt;1. GIL 是什么&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;GIL（Global Interpreter Lock，全局解释器锁）&lt;/strong&gt; 是 CPython 解释器的一个机制：&lt;strong&gt;它确保任何时刻只有一个线程在执行 Python 字节码。&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>Python 新手必看：10个渐进式开源项目助你快速入门到进阶</title><link>https://plumephp.com/gua-he-xin-shou-de-kai-yuan-xiang-mu-python-pian/</link><pubDate>Wed, 12 Aug 2026 17:00:00 +0800</pubDate><guid>https://plumephp.com/gua-he-xin-shou-de-kai-yuan-xiang-mu-python-pian/</guid><description>&lt;blockquote&gt;
&lt;p&gt;读完教程后第一个问题：&amp;ldquo;我应该做什么项目？&amp;ldquo;本文按&lt;strong&gt;难度分级&lt;/strong&gt;推荐 10 个项目，每个都说明你能学到什么、源码该怎么读、怎么参与贡献。不只是列链接，而是给你一张&amp;quot;项目学习地图&amp;rdquo;。&lt;/p&gt;</description></item><item><title>Python 学习资源终极路线图：从入门到就业的完整指南</title><link>https://plumephp.com/python-xue-xi-lu-xian-tui-jian/</link><pubDate>Wed, 12 Aug 2026 16:00:00 +0800</pubDate><guid>https://plumephp.com/python-xue-xi-lu-xian-tui-jian/</guid><description>&lt;blockquote&gt;
&lt;p&gt;学习编程最怕的不是&amp;quot;学不会&amp;quot;，而是&amp;quot;学偏了&amp;quot;。本文不丢给你一个链接列表就完事，而是给你一张清晰的路线图——什么阶段该学什么、学到什么程度、下一步该往哪走，全部帮你规划好。&lt;/p&gt;</description></item><item><title>pyproject.toml 配置完全手册：从 PEP 518 到现代 Python 项目管理</title><link>https://plumephp.com/pyproject-toml-wan-quan-shou-ce/</link><pubDate>Wed, 12 Aug 2026 15:00:00 +0800</pubDate><guid>https://plumephp.com/pyproject-toml-wan-quan-shou-ce/</guid><description>&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;pyproject.toml&lt;/code&gt; 是 Python 项目的&amp;quot;身份证&amp;quot;——它告诉构建工具如何打包你的代码，告诉编辑器如何格式化它，告诉 CI 如何测试它。本文从标准演进历史到逐字段解析，让你彻底掌握这份配置文件。&lt;/p&gt;</description></item><item><title>Python 进阶实战：倒计时猜数字（面向对象 + 异常处理 + 文件持久化）</title><link>https://plumephp.com/python-jiao-cheng-zhi-dao-ji-shi-cai-shu-zi/</link><pubDate>Wed, 12 Aug 2026 14:00:00 +0800</pubDate><guid>https://plumephp.com/python-jiao-cheng-zhi-dao-ji-shi-cai-shu-zi/</guid><description>&lt;blockquote&gt;
&lt;p&gt;如果你已经会写基础版的猜数字游戏，这篇文章将带你把它变成一个&lt;strong&gt;真正的软件&lt;/strong&gt;——有类结构、有状态管理、有持久化存储。这是从&amp;quot;会写代码&amp;quot;到&amp;quot;会写工程&amp;quot;的关键一跃。&lt;/p&gt;</description></item><item><title>Python 经典项目实战：从零实现猜数字游戏（含完整源码解析）</title><link>https://plumephp.com/python-jiao-cheng-zhi-cai-shu-zi-de-you-xi/</link><pubDate>Wed, 12 Aug 2026 13:00:00 +0800</pubDate><guid>https://plumephp.com/python-jiao-cheng-zhi-cai-shu-zi-de-you-xi/</guid><description>&lt;blockquote&gt;
&lt;p&gt;猜数字游戏是编程入门的&amp;quot;Hello World+&amp;quot;——它足够简单，几分钟就能跑通；又足够丰富，可以练习条件判断、循环、异常处理和用户交互。跟着本文完成这个项目，你的 Python 基础会更扎实。&lt;/p&gt;</description></item><item><title>Python asyncio 极速异步编程完全指南：从协程到高并发服务</title><link>https://plumephp.com/asyncio-wan-quan-zhi-nan/</link><pubDate>Wed, 12 Aug 2026 12:00:00 +0800</pubDate><guid>https://plumephp.com/asyncio-wan-quan-zhi-nan/</guid><description>&lt;blockquote&gt;
&lt;p&gt;Python 的 &lt;code&gt;asyncio&lt;/code&gt; 是解决 I/O 密集型任务的利器。本文不堆砌概念，而是带你从&amp;quot;为什么需要异步&amp;quot;到&amp;quot;写出能处理万级并发的服务&amp;quot;，走完完整路径。&lt;/p&gt;</description></item><item><title>Python 日期时间处理完全指南：datetime、zoneinfo、dateutil 与性能优化</title><link>https://plumephp.com/python-datetime-complete-guide/</link><pubDate>Wed, 12 Aug 2026 11:00:00 +0800</pubDate><guid>https://plumephp.com/python-datetime-complete-guide/</guid><description>&lt;blockquote&gt;
&lt;p&gt;日期时间处理是 Python 开发中最常见却也最容易出错的领域之一。本文从字符串解析到跨时区计算，从性能陷阱到企业级最佳实践，给你一个完整答案。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="目录"&gt;目录&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="#1-%E4%B8%BA%E4%BB%80%E4%B9%88%E6%97%A5%E6%9C%9F%E6%97%B6%E9%97%B4%E5%AE%B9%E6%98%93%E5%87%BA%E9%94%99"&gt;为什么日期时间容易出错&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#2-datetime-%E6%A8%A1%E5%9D%97%E6%A0%B8%E5%BF%83%E6%A6%82%E5%BF%B5"&gt;datetime 模块核心概念&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#3-%E6%97%A5%E6%9C%9F%E6%97%B6%E9%97%B4%E5%AF%B9%E8%B1%A1%E5%88%9B%E5%BB%BA%E4%B8%8E%E5%9F%BA%E6%9C%AC%E6%93%8D%E4%BD%9C"&gt;日期时间对象创建与基本操作&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#4-%E6%A0%BC%E5%BC%8F%E5%8C%96%E5%AD%97%E7%AC%A6%E4%B8%B2strftime-vs-strptime"&gt;格式化字符串：strftime vs strptime&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#5-%E6%97%B6%E5%8C%BA%E5%A4%84%E7%90%86%E4%BB%8E-pytz-%E5%88%B0-zoneinfo"&gt;时区处理：从 pytz 到 zoneinfo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#6-timedelta%E6%97%B6%E9%97%B4%E5%B7%AE%E8%AE%A1%E7%AE%97"&gt;timedelta：时间差计算&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#7-dateutil%E6%99%BA%E8%83%BD%E6%97%A5%E6%9C%9F%E8%A7%A3%E6%9E%90"&gt;dateutil：智能日期解析&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#8-%E5%B8%B8%E8%A7%81%E6%97%A5%E6%9C%9F%E5%9C%BA%E6%99%AF%E5%AE%9E%E6%88%98"&gt;常见日期场景实战&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#9-%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96%E4%B8%8E%E9%99%B7%E9%98%B1"&gt;性能优化与陷阱&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#10-%E6%97%A5%E6%9C%9F%E5%A4%84%E7%90%86%E9%80%9F%E6%9F%A5%E8%A1%A8"&gt;日期处理速查表&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="1-为什么日期时间容易出错"&gt;1. 为什么日期时间容易出错&lt;/h2&gt;
&lt;p&gt;在正式学习之前，先看几个常见的坑：&lt;/p&gt;</description></item><item><title>Python 10 分钟极速上手手册：从零开始写出你的第一行代码</title><link>https://plumephp.com/python-ru-men-kuai-jiao-cheng/</link><pubDate>Wed, 12 Aug 2026 10:00:00 +0800</pubDate><guid>https://plumephp.com/python-ru-men-kuai-jiao-cheng/</guid><description>&lt;blockquote&gt;
&lt;p&gt;这篇文章的目标：即使你从没写过任何代码，10 分钟后也能运行一个完整的小程序。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="目录"&gt;目录&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="#1-%E7%8E%AF%E5%A2%83%E5%87%86%E5%A4%87%E4%BD%A0%E9%9C%80%E8%A6%81%E7%9A%84%E5%8F%AA%E6%9C%89%E4%B8%A4%E6%A0%B7%E4%B8%9C%E8%A5%BF"&gt;环境准备：你需要的只有两样东西&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#2-%E7%AC%AC%E4%B8%80%E4%B8%AA%E7%A8%8B%E5%BA%8Fhello-world"&gt;第一个程序：Hello, World&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#3-%E5%8F%98%E9%87%8F%E4%B8%8E%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8Bpython-%E7%9A%84%E5%9F%BA%E6%9C%AC%E5%8D%95%E5%85%83"&gt;变量与数据类型：Python 的基本单元&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#4-%E8%BF%90%E7%AE%97%E7%AC%A6%E4%B8%8E%E8%A1%A8%E8%BE%BE%E5%BC%8F%E8%AE%A9%E6%95%B0%E6%8D%AE%E5%8A%A8%E8%B5%B7%E6%9D%A5"&gt;运算符与表达式：让数据动起来&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#5-%E5%AD%97%E7%AC%A6%E4%B8%B2%E6%93%8D%E4%BD%9C%E6%96%87%E6%9C%AC%E5%A4%84%E7%90%86%E7%9A%84%E8%89%BA%E6%9C%AF"&gt;字符串操作：文本处理的艺术&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#6-%E6%9D%A1%E4%BB%B6%E5%88%A4%E6%96%AD%E7%A8%8B%E5%BA%8F%E7%9A%84%E6%99%BA%E6%85%A7%E6%8A%89%E6%8B%A9"&gt;条件判断：程序的智慧抉择&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#7-%E5%BE%AA%E7%8E%AF%E9%87%8D%E5%A4%8D%E6%89%A7%E8%A1%8C%E7%9A%84%E5%8A%9B%E9%87%8F"&gt;循环：重复执行的力量&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#8-%E5%88%97%E8%A1%A8%E6%9C%89%E5%BA%8F%E7%9A%84%E9%9B%86%E5%90%88"&gt;列表：有序的集合&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#9-%E5%AD%97%E5%85%B8%E9%94%AE%E5%80%BC%E5%AF%B9%E7%9A%84%E6%98%A0%E5%B0%84"&gt;字典：键值对的映射&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#10-%E5%87%BD%E6%95%B0%E4%BB%A3%E7%A0%81%E7%9A%84%E5%A4%8D%E7%94%A8%E5%88%A9%E5%99%A8"&gt;函数：代码的复用利器&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#11-%E6%96%87%E4%BB%B6%E8%AF%BB%E5%86%99%E4%B8%8E%E5%A4%96%E9%83%A8%E4%B8%96%E7%95%8C%E4%BA%A4%E4%BA%92"&gt;文件读写：与外部世界交互&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#12-%E5%BC%82%E5%B8%B8%E5%A4%84%E7%90%86%E8%AE%A9%E7%A8%8B%E5%BA%8F%E6%9B%B4%E5%81%A5%E5%A3%AE"&gt;异常处理：让程序更健壮&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#13-%E5%AE%9E%E6%88%98%E5%B0%8F%E9%A1%B9%E7%9B%AE%E5%A4%A9%E6%B0%94%E6%9F%A5%E8%AF%A2%E5%8A%A9%E6%89%8B"&gt;实战小项目：天气查询助手&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#14-python-%E8%AF%AD%E6%B3%95%E9%80%9F%E6%9F%A5%E8%A1%A8"&gt;Python 语法速查表&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#15-%E4%B8%8B%E4%B8%80%E6%AD%A5%E5%AD%A6%E4%B9%A0%E8%AE%A1%E5%88%92"&gt;下一步学习计划&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="1-环境准备你需要的只有两样东西"&gt;1. 环境准备：你需要的只有两样东西&lt;/h2&gt;
&lt;h3 id="11-安装-python"&gt;1.1 安装 Python&lt;/h3&gt;
&lt;p&gt;Python 3.9+ 即可（推荐 3.11 或 3.12）。&lt;/p&gt;</description></item><item><title>Python 部署与分发：Docker、PyPI 发布与可复现环境</title><link>https://plumephp.com/python-deployment/</link><pubDate>Sat, 01 Aug 2026 13:30:00 +0800</pubDate><guid>https://plumephp.com/python-deployment/</guid><description>&lt;blockquote&gt;
&lt;p&gt;「在我的机器上可以跑」是部署的原罪。本文将 Python 应用从开发环境「封印」到生产环境，确保任何机器上行为一致。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="1-docker-多阶段构建"&gt;1. Docker 多阶段构建&lt;/h2&gt;
&lt;h3 id="11-基础-dockerfile"&gt;1.1 基础 &lt;a href="https://plumephp.com/posts/docker/"&gt;Dockerfile&lt;/a&gt;&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-dockerfile" data-lang="dockerfile"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# ========== Stage 1: Builder ==========&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;python:3.12-slim&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;builder&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;/app&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# 安装构建依赖&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;RUN&lt;/span&gt; apt-get update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt-get install -y --no-install-recommends &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; gcc &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; rm -rf /var/lib/apt/lists/*&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# 安装 Python 依赖到独立目录&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;COPY&lt;/span&gt; requirements.txt .&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;RUN&lt;/span&gt; pip install --no-cache-dir --user -r requirements.txt&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# ========== Stage 2: Production ==========&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;python:3.12-slim&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;/app&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# 创建非 root 用户&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;RUN&lt;/span&gt; useradd -m -u &lt;span class="m"&gt;1000&lt;/span&gt; appuser&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# 只复制必要的依赖&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;COPY&lt;/span&gt; --from&lt;span class="o"&gt;=&lt;/span&gt;builder /root/.local /home/appuser/.local&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;COPY&lt;/span&gt; ./app ./app&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# 设置环境&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;ENV&lt;/span&gt; &lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/home/appuser/.local/bin:&lt;span class="nv"&gt;$PATH&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;PYTHONDONTWRITEBYTECODE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;PYTHONUNBUFFERED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;USER&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;appuser&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;8000&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;CMD&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;uvicorn&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;app.main:app&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;--host&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;0.0.0.0&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;--port&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;8000&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="12-基于-uv-的优化版"&gt;1.2 基于 uv 的优化版&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-dockerfile" data-lang="dockerfile"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# 最小化镜像（基于 uv 官方镜像）&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;ghcr.io/astral-sh/uv:python3.12-bookworm-slim&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;/app&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# 启用编译缓存&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;ENV&lt;/span&gt; &lt;span class="nv"&gt;UV_COMPILE_BYTECODE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# 先复制 lock 文件（利用 Docker 层缓存）&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;COPY&lt;/span&gt; uv.lock pyproject.toml ./&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;RUN&lt;/span&gt; uv sync --frozen --no-install-project --no-dev&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# 再复制代码&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;COPY&lt;/span&gt; ./app ./app&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;RUN&lt;/span&gt; uv sync --frozen --no-dev&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# 运行&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;8000&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;CMD&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;uv&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;run&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;uvicorn&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;app.main:app&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;--host&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;0.0.0.0&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;--port&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;8000&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;镜像大小对比：&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>Python 测试与质量工程：pytest、mock 与覆盖率实战</title><link>https://plumephp.com/python-testing/</link><pubDate>Sat, 01 Aug 2026 13:00:00 +0800</pubDate><guid>https://plumephp.com/python-testing/</guid><description>&lt;blockquote&gt;
&lt;p&gt;测试不是质量 assurance，而是质量 feedback。好的测试让你「无所畏惧」地重构。本文建立完整的 Python 测试工程体系。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="1-pytest-基础"&gt;1. pytest 基础&lt;/h2&gt;
&lt;h3 id="11-为什么选择-pytest"&gt;1.1 为什么选择 pytest&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;特性&lt;/th&gt;
					&lt;th&gt;unittest&lt;/th&gt;
					&lt;th&gt;pytest&lt;/th&gt;
					&lt;th&gt;说明&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;断言写法&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;self.assertEqual&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;assert a == b&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;更直观&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Fixture&lt;/td&gt;
					&lt;td&gt;setUp/tearDown&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;@pytest.fixture&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;更灵活&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;插件生态&lt;/td&gt;
					&lt;td&gt;少&lt;/td&gt;
					&lt;td&gt;丰富（200+）&lt;/td&gt;
					&lt;td&gt;扩展性强&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;失败信息&lt;/td&gt;
					&lt;td&gt;基础&lt;/td&gt;
					&lt;td&gt;详细 diff&lt;/td&gt;
					&lt;td&gt;调试友好&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="12-快速上手"&gt;1.2 快速上手&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pip install pytest pytest-asyncio
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# test_calculator.py — 无需类，纯函数即可&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_add_positive&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_add_negative&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_add_zero&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;运行：&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>Python 现代工具链：uv + ruff + mypy 全链路工程实践</title><link>https://plumephp.com/python-modern-toolchain/</link><pubDate>Sat, 01 Aug 2026 12:30:00 +0800</pubDate><guid>https://plumephp.com/python-modern-toolchain/</guid><description>&lt;blockquote&gt;
&lt;p&gt;2024-2025 年 Python 工具链经历了革命性更新：&lt;code&gt;uv&lt;/code&gt; 以 &lt;a href="https://plumephp.com/posts/rust/"&gt;Rust&lt;/a&gt; 编写，替代 pip + virtualenv + poetry 的组合；&lt;code&gt;ruff&lt;/code&gt; 统一了 flake8 + black + isort 的功能。本文提供「一步到位」的现代化迁移方案。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="1-uv一站式-python-包管理器"&gt;1. uv：一站式 Python 包管理器&lt;/h2&gt;
&lt;h3 id="11-为什么选-uv"&gt;1.1 为什么选 uv&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;工具&lt;/th&gt;
					&lt;th&gt;安装速度&lt;/th&gt;
					&lt;th&gt;虚拟环境&lt;/th&gt;
					&lt;th&gt;Python 版本&lt;/th&gt;
					&lt;th&gt;依赖锁定&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;pip&lt;/td&gt;
					&lt;td&gt;慢（逐包下载）&lt;/td&gt;
					&lt;td&gt;需 virtualenv&lt;/td&gt;
					&lt;td&gt;无&lt;/td&gt;
					&lt;td&gt;requirements.txt&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;poetry&lt;/td&gt;
					&lt;td&gt;中等&lt;/td&gt;
					&lt;td&gt;内置&lt;/td&gt;
					&lt;td&gt;无&lt;/td&gt;
					&lt;td&gt;poetry.lock&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;uv&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;极速（并行+缓存）&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;内置&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;内置&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;uv.lock&lt;/strong&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;uv 由 Astral 团队（Rust 编写）开发，使命是替代 Python 工具链的「瑞士军刀」：&lt;/p&gt;</description></item><item><title>Python 数据科学与 AI：Pandas/Polars、PyTorch 推理与 ONNX 部署</title><link>https://plumephp.com/python-data-ai/</link><pubDate>Sat, 01 Aug 2026 12:00:00 +0800</pubDate><guid>https://plumephp.com/python-data-ai/</guid><description>&lt;blockquote&gt;
&lt;p&gt;Python 是 &lt;a href="https://plumephp.com/posts/ai/"&gt;AI&lt;/a&gt; 时代的英语。无论你用 &lt;a href="https://plumephp.com/posts/ml/"&gt;PyTorch&lt;/a&gt; 训练大模型，还是用 Polars 处理十亿行日志，这篇文章提供从数据到智能的完整工程地图。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="1-数据处理pandaspolars-与-numpy"&gt;1. 数据处理：Pandas、Polars 与 NumPy&lt;/h2&gt;
&lt;h3 id="11-三剑客选型"&gt;1.1 三剑客选型&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;工具&lt;/th&gt;
					&lt;th&gt;适用场景&lt;/th&gt;
					&lt;th&gt;性能&lt;/th&gt;
					&lt;th&gt;内存&lt;/th&gt;
					&lt;th&gt;特点&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;NumPy&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;数值计算、矩阵运算&lt;/td&gt;
					&lt;td&gt;⭐⭐⭐⭐&lt;/td&gt;
					&lt;td&gt;低&lt;/td&gt;
					&lt;td&gt;C 底层，广播机制&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Pandas&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;表格数据、&lt;a href="https://plumephp.com/posts/data-engineering/"&gt;ETL&lt;/a&gt;、分析&lt;/td&gt;
					&lt;td&gt;⭐⭐&lt;/td&gt;
					&lt;td&gt;高&lt;/td&gt;
					&lt;td&gt;成熟生态，索引灵活&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Polars&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;大数据集（&amp;gt;1GB）&lt;/td&gt;
					&lt;td&gt;⭐⭐⭐⭐⭐&lt;/td&gt;
					&lt;td&gt;低&lt;/td&gt;
					&lt;td&gt;&lt;a href="https://plumephp.com/posts/rust/"&gt;Rust&lt;/a&gt; 编写，惰性计算&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="12-numpy-核心技巧"&gt;1.2 NumPy 核心技巧&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;numpy&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;np&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 向量化替代循环（1000x 加速）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# ❌ 慢&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1_000_000&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# ✅ 快&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;arange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1_000_000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="c1"&gt;# 广播，无 Python 循环&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 高级索引&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;arr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;randn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;mask&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;arr&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="c1"&gt;# 布尔掩码&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;outliers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;mask&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;# 只取大于 2 的元素&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 内存视图（零拷贝）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;sub&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;# 不复制数据&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="13-pandas-实战模式"&gt;1.3 Pandas 实战模式&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;pandas&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;pd&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 读取大文件的 4 个技巧&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read_csv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;large.csv&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;usecols&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;user_id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;amount&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;timestamp&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="c1"&gt;# 只读需要的列&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;dtype&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;user_id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;int32&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;amount&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;float32&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="c1"&gt;# 降精度&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;parse_dates&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;timestamp&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;chunksize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;100_000&lt;/span&gt; &lt;span class="c1"&gt;# 分块处理&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 高效分组聚合&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# ❌ 慢：apply 调用 Python 函数&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;groupby&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;category&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;apply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;amount&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# ✅ 快：向量化聚合&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;agg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;groupby&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;category&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;agg&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;amount&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;sum&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;mean&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;count&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;user_id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;nunique&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 时间序列重采样&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 按小时统计订单量&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_index&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;timestamp&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;resample&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;H&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;order_id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="14-polars下一代-dataframe"&gt;1.4 Polars：下一代 DataFrame&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;polars&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;pl&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 惰性查询（查询优化类似 SQL 执行计划）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pl&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;scan_csv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;huge.csv&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# 不立即读数据&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;df&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pl&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;col&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;amount&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;group_by&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;category&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;agg&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;pl&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;col&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;amount&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;alias&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;total&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;pl&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;col&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;user_id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;n_unique&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;alias&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;unique_users&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;total&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;descending&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;collect&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;# 这里才真正执行&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 与 Pandas 互操作&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;pandas_df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_pandas&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;polars_df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pl&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_pandas&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pandas_df&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Polars vs Pandas 性能对比（1GB CSV）：&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>Python Web 框架：FastAPI、Flask 与 Django 深度对比与实战</title><link>https://plumephp.com/python-web-frameworks/</link><pubDate>Sat, 01 Aug 2026 11:30:00 +0800</pubDate><guid>https://plumephp.com/python-web-frameworks/</guid><description>&lt;blockquote&gt;
&lt;p&gt;2024 年的 Python Web 框架格局正在快速变化：FastAPI 以「类型驱动」和「原生异步」横扫 API 开发领域，Flask 凭借简洁守住中小型项目，Django 仍是全功能 CMS/Admin 的首选。本文从选型到部署，覆盖完整工程路径。&lt;/p&gt;</description></item><item><title>Python 类型系统与 Pydantic V2：从注解到极致运行时验证</title><link>https://plumephp.com/python-typing-pydantic/</link><pubDate>Sat, 01 Aug 2026 11:00:00 +0800</pubDate><guid>https://plumephp.com/python-typing-pydantic/</guid><description>&lt;blockquote&gt;
&lt;p&gt;渐进式类型是 Python 的骄傲——你可以从「零注解」的脚本平滑过渡到「全注解」的工程代码。本文覆盖完整路径。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="1-python-类型注解基础"&gt;1. Python 类型注解基础&lt;/h2&gt;
&lt;h3 id="11-内置类型python-39-语法"&gt;1.1 内置类型（Python 3.9+ 语法）&lt;/h3&gt;
&lt;p&gt;Python 3.9 起，内置集合类型支持泛型语法，无需导入 &lt;code&gt;typing&lt;/code&gt;：&lt;/p&gt;</description></item><item><title>Python 并发与性能：GIL、asyncio 与多进程的工程实践</title><link>https://plumephp.com/python-concurrency-performance/</link><pubDate>Sat, 01 Aug 2026 10:30:00 +0800</pubDate><guid>https://plumephp.com/python-concurrency-performance/</guid><description>&lt;blockquote&gt;
&lt;p&gt;本文假设 Python 3.11+。所有代码可直接复制运行。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="1-gil全局解释器锁的真相"&gt;1. GIL（全局解释器锁）的真相&lt;/h2&gt;
&lt;h3 id="11-什么是-gil"&gt;1.1 什么是 GIL&lt;/h3&gt;
&lt;p&gt;CPython 的 &lt;strong&gt;GIL（Global Interpreter Lock）&lt;/strong&gt; 是一个互斥锁，确保在任意时刻只有一个线程在执行 Python 字节码。&lt;/p&gt;</description></item><item><title>Python 发展史：众人的语言（第三卷）</title><link>https://plumephp.com/python-fa-de-yu-yan-di-san/</link><pubDate>Sun, 19 Oct 2025 10:29:02 +0800</pubDate><guid>https://plumephp.com/python-fa-de-yu-yan-di-san/</guid><description>&lt;h2 id="卷三专题群像多实现数据与-ai供应链并行新常态"&gt;卷三：专题群像（多实现·数据与 &lt;a href="https://plumephp.com/posts/ai/"&gt;AI&lt;/a&gt;·供应链·并行新常态）&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;不再按年份，而按“线”来讲：像把一座城分解成四条地铁——你可以在任意一站换乘，但每条线都有自己的节奏。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="第一线--多实现的交响同一门语言的多种体温"&gt;第一线 多实现的交响：同一门语言的多种体温&lt;/h2&gt;
&lt;h3 id="11-走廊里的圆桌兼容与速度的对话"&gt;1.1 走廊里的圆桌：兼容与速度的对话&lt;/h3&gt;
&lt;p&gt;大会午后的走廊很像一条不设防的论坛。几位维护者围坐成一圈：&lt;/p&gt;</description></item><item><title>Python 发展史：众人的语言（第二卷）</title><link>https://plumephp.com/python-fa-de-yu-yan-di-er/</link><pubDate>Sun, 19 Oct 2025 10:29:02 +0800</pubDate><guid>https://plumephp.com/python-fa-de-yu-yan-di-er/</guid><description>&lt;h2 id="卷二新常态与长加速20132025"&gt;卷二：新常态与长加速（2013—2025）&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;这一卷里，Python 不再只是一门“语言”，它同时是&lt;strong&gt;分发生态、类型系统、运行时工程、社区治理&lt;/strong&gt;的复合体。我们把镜头拉近：看人，看会场里的白板，看邮件列表上的折返跑。&lt;/p&gt;</description></item><item><title>Python 发展史：众人的语言（第一卷）</title><link>https://plumephp.com/python-fa-de-yu-yan-di-yi/</link><pubDate>Sun, 19 Oct 2025 10:28:02 +0800</pubDate><guid>https://plumephp.com/python-fa-de-yu-yan-di-yi/</guid><description>&lt;blockquote&gt;
&lt;p&gt;讲述一门语言如何从一个人的夜晚，成长为无数人的白昼。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="序幕冬夜的终端光1989阿姆斯特丹"&gt;序幕：冬夜的终端光（1989，阿姆斯特丹）&lt;/h2&gt;
&lt;p&gt;午夜后的走廊安静得只剩暖气声。CWI 的办公室里，老旧显示器泛着蓝绿的微光。Guido 拿起杯子，杯里只剩冷掉的咖啡。他把外套搭在椅背上，重新坐回键盘前。&lt;/p&gt;</description></item><item><title>Python 极简入门教程</title><link>https://plumephp.com/python-ru-men-cheng/</link><pubDate>Fri, 17 Oct 2025 10:28:02 +0800</pubDate><guid>https://plumephp.com/python-ru-men-cheng/</guid><description>&lt;h2 id="python-极简入门教程精炼但全面"&gt;Python 极简入门教程（精炼但全面）&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;目的：用一份“最短路径但不失全面”的教程，把你从 0 带到能写出可维护、可发布的小项目。尽量以标准库为主，减少外部依赖；每节都有&lt;strong&gt;可复制即用&lt;/strong&gt;的示例与练习。&lt;/p&gt;</description></item></channel></rss>