编程语言

Go、Python 等语言实践与实现记录。

专题分组

下级分类

2 个下级
Python 开发
4 分钟

Python 异步编程 async 处理规则

这篇笔记围绕 Python 异步服务中哪些操作该 await、哪些不能指望 async 加速这一边界展开,适合在 FastAPI 等事件循环模型下处理接口、数据库、缓存、对象存储和本地计算任务的开发者参考。文章先强调网络 I/O 本身不消耗 CPU,调用 OpenAI、数据库、Redis、S3 等等待型操作时,应使用 httpx、asyncpg、motor 等异步库并显式 await,让主线程在等待网络返回时继续处理其他请求。随后区分 CPU/内存密集任务:Pandas 处理 Excel、视频转码、哈希计算或超长循环即使写进 async def,也仍会占用主线程并卡住 Event Loop,协程语法不会把单线程计算变成并行计算。针对这类阻塞,文章给出两类“扔到池子里”的处理方式:优先用 asyncio.to_thread 或线程池释放事件循环,尤其适合 Excel 解析、图片处理和许多 Pandas/Numpy 操作,因为其底层 C 实现可能在重计算或 I/O 时释放 GIL。对于纯 Python 重计算,文中建议使用 ProcessPoolExecutor 绕开 GIL,但同时提醒进程创建、序列化传输和无法共享内存都会带来更高成本。最后还提供了一个 AsyncWrapper 示例,用 __getattr__ 将同步厂商 SDK 方法统一包装成 await asyncio.to_thread(...) 的异步调用形式,用较小线程切换开销换取异步服务对旧同步接口的兼容。

Python 开发
1 分钟

ubuntu 使用 Miniconda

这份笔记记录了在 Ubuntu 64 位环境中安装和初始化 Miniconda 的最小流程,适合需要为 Python 项目隔离依赖、但不想安装完整 Anaconda 的用户。正文先给出通过 wget 下载 Miniconda Linux x86_64 安装脚本、再用 bash 执行安装的命令,覆盖了从获取安装包到启动安装器的基本入口。安装完成后,作者特别建议关闭默认自动进入 base 环境,并使用 conda config --set auto_activate_base false 避免 shell 启动时污染全局命令行环境。由于 Anaconda 更新了服务条款,笔记还补充了通过 conda tos accept 分别接受 pkgs/main 和 pkgs/r 官方频道条款的命令,否则后续下载包可能受阻。环境管理部分以运行 Ollama 脚本或 Milvus Python 代码为例,建议创建名为 ai_tools 的 Python 3.10 环境,并给出创建、激活、退出和查看已安装包的常用命令。这更像是一份快速备忘清单,重点在可直接复制执行的配置步骤,适合 Ubuntu 上进行 AI 工具、向量数据库或其他 Python 实验项目的开发者参考。

Go 开发
2 分钟

Cursor 配置 Go debug 模式

这份速查记录聚焦在 Cursor 中为 Go 项目启用调试模式,配置入口是项目目录下的 .vscode/launch.json。正文给出两套可直接复制的 launch 配置:第一套使用 type 为 go、request 为 launch、mode 为 auto,并将 program 设置为 ${fileDirname},适合从当前文件所在目录快速启动,也提示可改为 workspace 下的 main.go 或 cmd/server 等入口目录。第二套配置将 mode 显式改为 debug,以 ${workspaceFolder}/main.go 作为程序入口,同时设置 cwd、dlvToolPath、环境变量、showLog 和 verbose trace,便于在开发环境中固定调试参数并输出更详细的 Delve 日志。需要注意的是,示例里的 dlvToolPath 使用了本机绝对路径,迁移到其他机器或团队项目时应按实际安装位置调整;环境变量如 GIN_MODE、GOPROXY、GOEXPERIMENT 也应与项目运行要求匹配。它适合已经具备 Go、Cursor/VS Code Go 调试支持和 dlv 基础环境的开发者,用来快速搭建单入口项目或当前目录入口的调试配置。

Cursor 配置 python debug 模式开发
Python 开发
5 分钟

Cursor 配置 python debug 模式开发

从 PyCharm 迁移到 Cursor 调试 Python 项目时,最容易遇到的问题是模块导入路径不再由 IDE 自动补齐,导致运行当前文件时出现 ModuleNotFoundError。文章给出的常规做法是在项目下创建 .vscode/launch.json,配置 Python launch 任务,并通过 env 中的 PYTHONPATH: ${workspaceFolder} 手动把工作区加入模块搜索路径,相当于复刻 PyCharm 的 Mark Directory as Sources Root。它也解释了 Python 默认只会搜索标准库、site-packages 和当前脚本目录,因此在 VS Code/Cursor 这类编辑器中需要显式声明项目根路径。针对 conda 环境,文章进一步给出 settings.json 中固定 python.defaultInterpreterPath,以及 launch.json 中指定 python 解释器路径、保留 PYTHONPATH、设置 PYTHONUNBUFFERED=1 的配置方式,以便调试控制台正常输出日志。需要注意的是,Python Environment Manager 等环境管理插件可能在选择环境时自动重写 settings.json,与 launch.json 中的解释器配置冲突,并引发 permission denied,因此作者建议删除相关插件。整体适合正在从 PyCharm 转向 Cursor、希望降低内存占用但仍保留 Python 单文件调试和 conda 环境调试能力的开发者参考。

Fastapi 最快的序列化返回-ORJSONResponse
Python 开发
7 分钟

Fastapi 最快的序列化返回-ORJSONResponse

这篇笔记聚焦 FastAPI 中使用 ORJSONResponse 提升 JSON 响应序列化性能的原因与配置方式,核心场景是接口返回大列表、大 JSON 或包含时间字段等复杂类型的数据库记录。正文将默认 JSONResponse/标准库 json 与 orjson 的路径拆开比较:前者通常先把 Python 对象转换成 Python str,再由 Web 层编码成 UTF-8 bytes;orjson 则直接生成可网络传输的 UTF-8 字节,减少一次全量内存拷贝和编码转换。文章还解释了 orjson 采用 Rust 实现、面向速度优化并利用 SIMD 的背景,以及它对 datetime、UUID、numpy、dataclasses 等类型的原生支持如何避免频繁回调 Python 函数,从而降低额外开销和 GIL 争用。实践部分给出安装 orjson、导入 ORJSONResponse,并通过 FastAPI(default_response_class=ORJSONResponse) 设置全局默认响应类的示例。性能判断上,文中认为纯序列化微基准可能达到标准库的 5 到 10 倍,但在真实 Web 接口里收益取决于响应体大小和瓶颈位置。对于只返回极小 JSON 的接口,网络 IO 可能掩盖差异;而返回几千行记录、数 MB JSON 或大量 datetime 字段时,ORJSONResponse 更可能带来可感知的响应时间下降。

fastapi
Python 开发
10 分钟

Catch-All 路由

Catch-All 路由指用 FastAPI 的 `/{full_path:path}` 这类 `path` 类型路径参数匹配任意层级 URL 的兜底路由,常见于前端 SPA 路由回退、后台管理插件或静态资源兜底处理。文章先区分了默认 `str` 参数只匹配单段路径,而 `path` 会连同斜杠一起接收多段路径,因此 `/api/does-not-exist` 这类未命中精确接口的请求不会直接 404,而可能进入 fallback 处理函数。重点风险在路由注册顺序:FastAPI 按注册先后匹配,若 SQLAdmin 等插件提前注册了 catch-all,后续业务 router 可能被截获,导致本应进入 `/api/v1/**` 的请求落到兜底逻辑。文章还把这种顺序问题和浏览器 CORS 报错关联起来,说明 OPTIONS 预检请求在目标接口未注册、被覆盖或 catch-all 不支持 OPTIONS 时,可能得到 404/405 且缺少跨域响应头,最终表现为跨域失败。处理方式包括先注册所有业务接口,再注册 SQLAdmin 或其他兜底路由,并让 catch-all 使用 `api_route(..., methods=["GET", "POST", "OPTIONS"])` 显式接住 OPTIONS。若不希望业务逻辑处理预检,也可以单独添加 `@router.options("/{full_path:path}")` 返回空响应,保证预检请求有合法 handler。适合正在排查 FastAPI 路由“莫名其妙被命中”、后台插件干扰 API、或未命中接口却显示 CORS error 的后端开发者参考。

api-开发
Python 开发
13 分钟

接口等幂处理

接口等幂讨论的是 Web/API 在重复请求、自动重试或并发调用下如何避免重复修改系统状态,核心判断标准是同一操作执行多次后业务结果一致且不产生额外副作用。文章先用 HTTP 方法语义区分 GET、DELETE、PUT、POST 的等幂差异:查询、删除和“更新为固定状态”通常可视为等幂,而创建类 POST 容易产生重复资源,因此在支付、下单、扣积分等场景尤其需要防重。针对 PUT,文中强调理论语义和工程实现并不总是一致,即使请求体相同,也可能因 update_time、变更日志、审计表、MQ 消息、缓存刷新等动作破坏等幂。推荐做法是在更新前比较新旧数据,未变化时跳过写入和时间戳更新,或让日志、消息、缓存等副作用只在内容真正变更时触发。对于短时间重复提交或并发请求,文章给出基于 Redis 的幂等锁与状态缓存思路:用 idempotent key 标识一次操作,已处理则直接返回,未处理才执行业务逻辑。最后比较前端生成结构化 UUID 与后端令牌模式,认为完全随机 UUID 难以识别同一业务操作,而后端生成并下发幂等 key 更便于控制生命周期、缓存执行结果和保障支付、提交订单等关键接口的安全性。

api-开发
Python 开发
13 分钟

单例模式-介绍

这篇笔记以 Python 中的单例模式为对象,说明“一个类在程序运行期间只创建一个全局共享实例”的适用场景,包括配置管理、日志器、数据库连接池、线程池、缓存和 RedisClient 等需要复用状态或资源的对象。内容先对比懒汉式与饿汉式:前者在第一次使用时通过 `__new__` 创建实例,节省资源但在多线程并发判断 `_instance is None` 时可能产生多个对象;后者在模块加载时提前创建,写法简单且天然线程安全,但可能带来不必要的启动资源占用。针对懒汉式的并发问题,文章给出基于 `threading.Lock` 的双重检查锁实现,用外层判断减少加锁开销,用锁内二次判断避免多个线程排队后重复初始化。随后还展示了装饰器封装单例的函数式写法,并提醒其存在首次参数不可重设、默认线程不安全、只在进程内生效等边界。更 Pythonic 的方案是直接利用模块作为单例:`import` 会通过 `sys.modules` 缓存模块对象,使配置、全局状态或缓存变量在多个引用方之间共享。最后补充了 `threading.Lock` 的 acquire、release 和 `with lock` 用法,以及死锁、加锁粒度过大、共享状态污染和测试耦合等风险,适合正在学习 Python 设计模式和多线程资源保护的开发者。

设计模式
Python 开发
19 分钟

Alembic使用

这篇笔记围绕 FastAPI 项目中使用 SQLAlchemy 异步 ORM 与 PostgreSQL 时如何接入 Alembic 做数据库迁移展开,先说明 Alembic 通过迁移脚本和数据库中的 alembic_version 表来记录结构变更,并依靠 upgrade、downgrade 支持版本升级与回滚。配置部分重点放在 alembic.ini 的 script_location、初始化后生成的 env.py、versions 目录以及数据库连接地址,其中 env.py 需要手动接入项目配置、Base.metadata 和异步引擎,才能让 autogenerate 正确比对模型变化。文章给出一份异步迁移示例:加载项目根路径、读取 settings.DATABASE_URL、动态导入所有 models、使用 create_async_engine 和 connection.run_sync 执行在线迁移,同时在离线模式下生成 SQL。针对 FastAPI 与 Django 共用数据库的场景,示例通过 include_object 排除 django_session、auth_user、django_migrations 等 Django 相关表,避免 Alembic 误管理不属于当前服务的表结构。数据库层还记录了 DATABASE_URL 的拼接方式、Base 的作用、异步 Session 工厂以及 pool_size、max_overflow、pool_timeout、pool_recycle 等连接池参数。迁移命令部分覆盖 PYTHONPATH 设置、revision --autogenerate、upgrade head、history、upgrade/downgrade 指定版本和 downgrade base,并特别提醒迁移文件版本必须与数据库 alembic_version 对齐,新库初始化时不要混用旧版本文件。最后补充多环境迁移隔离思路,可通过不同 alembic 配置文件或在 env.py 中读取环境变量来切换版本目录,适合正在为异步 FastAPI 服务建立可控数据库版本管理流程的后端开发者参考。

谷歌tts使用与一次性生成sdk
Python 开发
15 分钟

谷歌tts使用与一次性生成sdk

这是一篇围绕 Google Cloud Text-to-Speech 快速接入与一次性生成音频文件的实践记录,适合需要在 Python 服务中把文本转换为语音并落地为文件的开发者参考。文章先从 Google Cloud 控制台入口、价格信息和每月 100 万字符免费额度讲起,随后展示启用 TTS API、创建凭证、生成服务账号密钥、赋予权限并下载 JSON 文件的配置路径。代码部分没有直接读取本地密钥文件,而是把服务账号中的 project_id、private_key、client_email、token_uri 等字段拆入环境变量和配置类,再通过 service_account.Credentials.from_service_account_info 初始化 TextToSpeechClient。一次性合成 SDK 封装为异步 synthesize 方法,支持传入文本、输出路径、language_code、ssml_gender 和 audio_encoding,并用 asyncio.to_thread 调用同步的 synthesize_speech,再通过 aiofiles 写入 MP3、LINEAR16 或 OGG_OPUS 文件。示例还演示了生成 output.mp3 后衔接 MinIO 上传,适合需要把合成音频继续发布到对象存储或 CDN 的场景。文末补充了 TTS 参数含义和云端合成链路,包括文本规范化、音素与韵律预测、神经合成、编码封装等概念,帮助读者理解一次性返回 audio_content 背后的处理流程。