Dealing With Grabage in Python

Grabage Collection In Python 本篇文章介绍 Python 中的 Grabage Collection (GC) 机制介绍 What’s Python Object? Python 对象中有三样东西: 类型(Type)、值(value)和引用计数(reference count), 当给变量命名时, Python 会自动检测其类型, 值在定义对象时声明, 引用计数是指该对象名称的数量. 首先来看一个类 class Person: def __init__(self, name, unique_id, spouse): self.name = name self.unique_id = unique_id self.spouse = spouse def __del__(self): print( # !r: 调用 repr() 来获取该对象的字符串表达式 # !s: str() # !a: ascii() f"Object {self.unique_id!r} is about to be removed from memory. Goodbye!" ) 该 Person 类有以下3个属性: name: 人名 unique_id: 唯一性 id spouse: 将为 None 或者将存储另一个 Person 对象 有一个特殊方法 __del__(), 这个特殊方法有一定的误导性. 该方法并不像 __len__() 与 len() 或者 __iter__() 与 iter() 那样与 del 关键字相关联. __del__() 特殊方法并不定义当对对象引用时 del 会发送什么, 相反, __del__() 是一个终结器 finaliser: 它在对象被消毁之前从内存中移除之间被调用. 因此, __del__() 中 print() 调用的字符串仅在 Python 即将从内存中移除对象时显示. ...

September 8, 2025 · 2 min · 241 words · Starslayerx

How AI Assistants Make Precise Edits to Your Files

之前的文章介绍了如何制作一个基本的 AI 编程助手, 今天更近一步, 探讨 AI 助手如何对文件进行精确的修改. 实际的 AI Agent 不会读取所有的项目代码, 一般只会读取当前文件的代码, 当需要时才会去读取相关的代码文件. 然而, 输出也不会输出要修改的整个文件的代码, 因为这样输出不仅很慢, 同时成本也很高, 会有大量重复代码导致浪费(以 deepseek 为例, 输出 token 的价格是输入 token 价格的3倍, 是缓存命中输入 token 价格的24倍!), 因此一般是让模型输出要修改的代码和修改后的代码. 既然不能一次输出文件的所有代码, 这就引出了一个问题: 如何精确的修改代码文件? 首先要确定一种让模型准确地描述修改的格式, 并且提供健壮的格式匹配与错误重试机制(模型输出代码可能少个空格或者Tab), 这篇文章对这个问题做了探讨. 将 AI agent 生成的代码直接修改到文件中是一项核心能力, 然而实际上这常常出乎意料的困难, agent 可能会提出一个代码修改方案, 但实际修改却失败, 例如"找不到匹配的上下文"之类的错误, 需要手动干预. 许多 AI 编程助手的开发者都遇到过这种情况, 虽然 AI 理解代码的意图, 但将这种理解转化为精确的文件修改却带来了重大的技术挑战. Why Precise File Editing Matters 为什么精确的文件编辑至关重要 有效的文件编辑是编程助手的价值核心, 如果其不能可靠的修改文件, 需要人为手动修改, 就退化成了 AI 聊天引擎, 相比之下, 一个能够可靠自动化编辑的助手可以为开发者节省大量时间和认知负担. 根本的挑战在于, LLM 缺乏直接的文件系统访问权限, 他们必须通过专门的工具来描述预期的修改, 然后这些工具或 API 解释指令并尝试执行, LLM 的描述与文件系统状态之间的这种交接是常见的问题来源. 使用 GitHub Coplit、Aider、RooCode 或 Cursor 等工具的用户可能已经观察到这些问题: 编辑器无法找到正确的插入点、缩进不正确, 或者工具最终请求手动应用. ...

September 2, 2025 · 7 min · 1373 words · Starslayerx

Make an AI Coding Agent in python

这篇文件介绍如何使用 Python 制作一个基础的 AI 编程助手 Minimal AI Coding Agent 下面是一个 AI Coding Agent 至少需要的功能 Chat loop 对话循环 Call an LLM 调用大语言模型 Add tools to call 增加工具调用 Handle tool request 处理工具调用请求 Step 1: Chat Loop 首先, 聊天循环一直循环等待用户输入, Python 的 “input” 方法可以获取用户输入 print("Type q to quit") while True: user_message = input("You: ") if user_message == "q": break ai_message = f"You said {user_message}... so insightful" print(ai_message) 目前主流的 LLM 都是无状态的, 所以需要我们手动的去管理对话上下文, 这里使用一个 fake_ai 函数模拟真实的 LLM 调用, 并包含 role 和 content 内容 ...

September 1, 2025 · 11 min · 2265 words · Starslayerx

Asyncio vs Gevents in Python

python 中 asyncio 和 gevent 是两种协程(在一个线程内实现并发)的实现, 这篇文章对比介绍这两者实现. 下面先介绍一下基础概念: Coroutines 协程 在 Python 中, 协程是可以暂停和继续运行的函数, 使得其是否适合并发编程. 定义使用 async def 语法, 协程运行编写非阻塞的操作. 在协程内, await 关键字用于暂停执行, 直到给定的任务完成, 从而运行其他协程在此其间并发运行. Event Loop 事件循环 事件循环是一种控制结构, 它不断地处理一系列事件, 处理任务并管理程序的执行流程. 等待事件发生, 处理后再等待下一个事件. 这种机制确保程序能够以高效有序的方式响应事件, 例如用户输入、计时器或者消息. 下面是事件循环如何管理协程: 任务提交: 当向事件循环提交一个协程时, 其被封装在一个 Task 对象中, 然后任务被安排在事件循环上运行. 内部队列: 事件循环使用几个内部数据结构来管理和调度这些任务 就绪队列 (Ready Queue): 包含可以立即运行的任务. I/O 选择器 (I/O Selector): 监控文件描述符, 并根据 I/O 准备情况调度任务 计划回调 (Scheduled Callbacks): 管理计划在一定延迟后运行的任务. 调度: 事件循环不断检查这些队列和数据结构, 以确定哪些任务已准备好执行. 然后它运行这些任务, 在遇到 await 语句时, 根据需要暂停和恢复它们. 并发管理: 通过交错执行多个协程, 事件循环无需多个线程即可实现并发. 在任何时候, 只有一个任务会运行, 但如果一个任务是 I/O 密集型的, 它会切换到另一个任务, 给人一种并行的错觉. ...

August 29, 2025 · 4 min · 694 words · Starslayerx

Prompt Organization

这篇文章旨在介绍 Python 中常用的提示词组织方式 f-string 使用 f 字符串填充变量得到提示词 def get_prompt(query: str) -> list[dict]: SYSTEM_PROMPT = f"""... ... 多行提示词, 也可以填充变量 """ USER_PROMPT = f"""INPUT: {query} .... """ return [ {"role": "system", "content": SYSTEM_PROMPT}, {"role": "user", "content": USER_PROMPT}, ] 这种方法实现简单, 速度快, 但是: 多行字符串由于填充变量的需要, 需写在函数内, 导致代码格式混乱 # 实际上, 多行字符串还可以这样实现, 但也不太时候提示词太多的时候, 但这样代码格式会更加优雅 system_prompt = ( f"你是一名{role}负责...\n" f"具体规则:\n" f"1. ...." f"2. ...." ) 上面这种方法会将多行字符串合并, 注意不要加逗号, 不然就变成元组了 通过代码构造提示词, 任何修改都需要修改代码, 扩展性差 string.Template 使用 Python 元素字符串模板 SYSTEM_PROMPT = string.Template("""你是一名$role 多行提示词... """) USER_PROMPT = string.Template("""INPUT: $query """) def get_prompt(role: str, query: str) -> list[dict]: system_prompt = SYSTEM_PROMPT.subtitute(role="助手") user_prompt = USER_PROMPT.subtitute(query="问题...") return [ {"role": "system", "content": system_prompt}, {"role": "user", "content": user_prompt}, ] 使用模板字符串, 模板则不必写在函数内, 且模板字符串可以选择替换部分变量, 使用 .safe_substitute()方法传入一个字典, 例如 {"query": "问题..."}, 对没有传入的变量解析为 $var 对比 f-string, 模板字符串更加灵活, 且可以只传入部分值 ...

August 28, 2025 · 2 min · 305 words · Starslayerx

From Python to Go

From Python to Go: Why We Rewrote Our Ingest Pipeline at Telemetry Harbor 我们将 Telemetry Harbor 的摄取管道从 Python FastAPI 重写为 Go,原因是遇到了严重的性能瓶颈。迁移后,效率提升了 10 倍,数据完整性因严格类型检查而得到加强,系统也拥有了稳定、可扩展的高并发时间序列数据摄取基础。 背景:打造一个时间序列数据平台 Telemetry Harbor 源自我们在汽车行业积累的经验。几乎每个项目都要重复搭建相同的基础设施:数据库、后端、数据摄取管道、可视化界面。每次都要花费数周时间,这让我们萌生了打造一个开箱即用平台的想法。 当时的市场方案并不理想。InfluxDB 的商业化策略让许多关键特性被锁在付费墙后,版本迁移成本高且在大数据负载下表现不佳。TimescaleDB 与 ClickHouse 技术上更强大,但依旧需要用户自行构建后端与摄取管道。我们看到了缺口——需要一个极简、可靠、可直接使用的平台。 Python FastAPI:原型开发的正确选择 MVP 阶段,我们在开发速度与运行性能之间权衡。最终选择了 Python FastAPI,因为它允许我们: 快速验证市场假设 迅速收集客户反馈并迭代 在低成本下尝试多种方案 尽快上线以抢占市场 早期架构非常直接:HTTP API(避免防火墙问题)、Redis + RQ 队列、TimescaleDB。测试效果良好,但很快暴露了性能隐患——RQ 的同步处理方式无法支撑高吞吐场景。 性能瓶颈:Python 无法跟上增长 随着数据量上升,性能问题逐渐浮现: 空闲 CPU 占用:10% 中等负载:约 40% CPU 高负载:120–300% CPU(峰值 800%),频繁崩溃 问题不仅在于 RQ 的同步限制,而是整个 Python 架构在常规负载下都难以维持稳定。这迫使我们考虑全面重写。 迁移决策:为什么选择 Go? 我们评估了 Rust 和 Go: ...

August 27, 2025 · 1 min · 148 words · Starslayerx

Documenting REST APIs with OpenAPI

本章介绍如何使用 OpenAPI 来为 API 编写文档. OpenAPI 是描述 RESTful API 最流行的标准, 拥有丰富的生态系统, 可以用于测试、验证和可视化 API. 大多数编程语言都支持 OpenAPI 规范的库. OpenAPI 使用 JSON Schema 来描述 API 的结构和模型, 因此首先介绍 JSON Schema 的工作原理. JSON Schema 是一种用于定义 JSON 文档结构的规范, 包括文档中值的类型和格式. Using JSON Schema to model data 使用 JSON Schema 对数据建模 JSON Schema 是一种规范标准, 用于定义 JSON 文档的结构及其属性的类型和格式. JSON Schema 规范通常定义一个具有特定属性或特性的对象, 由键值对的关联数组表示, 如下面这样: { "status": { "type": "string" } } 在 JSON Schema 规范中, 每个属性都以键值对的形式出现, 其中值是该属性的描述符 一个属性最基本的描述符就是 type, 上面例子中, 指定类型为字符串 JSON Schema 支持以下基本数据类型: ...

August 25, 2025 · 9 min · 1727 words · Starslayerx

Rust Alternaitve Tools

常用工具的 rust 替代品. Introduction 在 Unix 生态中, 许多命令行工具都是用 C 编写的, 经过几十年的优化, 性能和稳定性都非常优秀. 然而, 近年来, Rust 以其安全性、内存管理优势和现代化开发体验, 成为系统级工具开发的理想选择. 首先更新 cargo, 不同系统都可以使用 cargo 安装, 当然也可以使用系统的包管理器安装 rustup update stable 有需要的话修改源, 一般在 ~/.cargo/config.toml, 下面是科大源 [source.crates-io] replace-with = 'ustc' [source.ustc] registry = "sparse+https://mirrors.ustc.edu.cn/crates.io-index/" [registries.ustc] index = "sparse+https://mirrors.ustc.edu.cn/crates.io-index/" Filesystem & Archiving 文件系统与归档 exa 替代 ls: 彩色支持 Git 状态的 ls 替代品 常用参数: -1: 一行显示一个文件 -l: 显示文件细节信息 -F: 在目录文件名末添加斜杠符号 -T: 树状显示 -R: 递归显示所有文件 --icons: 显示图标 zoxide 替代 cd: 基于访问频率的快速目录跳转工具 常用参数: z foo # 匹配 foo 的路径 z foo bar # 匹配 foo & bar 的路径 z - # 回到之前目录 zi foo # fzf File & Text Processing 文件与文本处理 bat 替代 cat: 具备语法高亮、行号显示、Git 集成等功能, 让查看文件内容更加美观 ripgrep 替代 grep: 使用 Rust 编写的极速文本搜索工具, 支持递归搜索、正则表达式、忽略规则(.gitignore)等 fd 替代 find: 提供简单直观的语法、更快的搜索性能, 并默认支持彩色输出和忽略 .gitignore 文件 System Monitoring & Management 系统监控与管理 bottom 替代 top / htop: 一个现代化的系统资源监控工具, 支持 CPU、内存、磁盘、网络等多种指标显示, 并提供交互式界面 procs 替代 ps: 更人性化的进程信息显示, 支持彩色输出、树状显示、搜索与过滤 Wrapping up Rust 的安全性和高性能使其成为编写现代 Linux 工具的理想选择. 这些替代品不仅提供了更好的用户体验, 还利用 Rust 的并发优势和零成本抽象提升了性能. 其他一些 rust 工具: ...

August 23, 2025 · 1 min · 160 words · Starslayerx

Tokei

Tokei 介绍 Tokei是一款 Rust 编写的开源工具, 用于统计项目代码行数, 支持上百种语言, 能够扫描整个代码库, 包括: 语言 文件数量 代码行数 注释行数 空行数 得益于 Rust 的高性能实现, Tokei 即使在超大规模代码库中也能保持极快的统计速度 (Rust 轮子真不错) 安装 brew install tokei 或者 cargo install tokei 使用 在项目根目录执行 tokei . 输出类似下面这样 =============================================================================== Language Files Lines Code Comments Blanks =============================================================================== Dockerfile 1 25 9 8 8 Python 52 2914 2372 96 446 TOML 1 65 58 0 7 YAML 2 49 45 0 4 ------------------------------------------------------------------------------- Markdown 1 194 0 158 36 |- BASH 1 13 13 0 0 (Total) 207 13 158 36 =============================================================================== Total 57 3247 2484 262 501 ===============================================================================

August 22, 2025 · 1 min · 93 words · Starslayerx

IEEE-754 Introduce

IEEE 754 标准数值类型及分类 整数 Integer 整数是没有小数部分的值, 在计算机内通常有两种表示方式: 有符号整数: 可以表示正数和负数, 最常用的是二补码表示. 例如 8 位二进制的范围为[-2^7, 2^7-1] 无符号整数: 仅表示非负数, 8 位二进制的范围为 [0, 2^8-1] 其中补码(Two’s Complement)用于表示负数 正数补码与原码相同 负数的补码 = 该数绝对值的二进制取反 + 1 通过补码, 可以使得加减运算统一, 溢出检测更加简单 浮点数 Floating-point 浮点数用于表示带小数的实数, 尤其适合科学计算和近似表示很大或很小的数值. IEEE 754 定义了浮点数的标准格式, 类似科学计数法: value = (-1)^(sign) x mantissa x 2^(exponent) 浮点数由三部分组成: 符号位 sign: 0/1代表正负 阶码 exponent: 通常使用偏移表示法 尾数 fraction/mantissa: 小数部分 常见浮点数类型: 单精度 float32: 1 位符号 + 8 位阶码 + 23 位尾数 双精度 float64: 1 位符号 + 11 位阶码 + 52 位尾数 浮点数的分类 Categories 以 64 精度为例 ...

August 18, 2025 · 2 min · 363 words · Starslayerx