墨穗app.notebase.cn
控制台
内容库
动态
管理
账户
U
用户
--
在线
v1.0.165 · 墨穗笔记
笔记

Notebase墨穗
静水流深,落墨成穗。

0笔记
0工具
30推荐

分类导航

按主题直达

编辑精选

站内用户贡献 · 真实笔记

最新收录

每日更新
继续浏览全部内容 →

笔记

0
加载中...

工具

0

此页用于记录用户反馈问题后的每一次改进

关于

笔记用法

“写笔记”支持四种格式——Word 文档、Excel 表格、Markdown、纯文本,起稿或二次编辑时都能随时切换,同一篇笔记想用哪种形态来记,都由你说了算。

md、txt、csv、json 这类纯文本则原样载入,不做多余加工。拿一张现成的表倒进来、改几笔、再导出去,等于白用一台免费的格式转换器。

要带走就在右上角点“下载”,可导出 PDF、Word、Markdown、Excel、TXT 等格式;列表卡片“⋯”菜单里,也有同样的下载入口。

工具用法

在“工具”页点“+ 上传工具”即可发布:填好名称与链接,再用 Markdown 把使用方法写清楚——能解决什么问题、怎么装、怎么用,比堆介绍实在。

要分发安装包就一并上传压缩包(ZIP、RAR、7Z、TAR.GZ,最大 35MB),别人在详情页一键下载;只放链接不带附件也可以。

工具按大家的收藏热度排序,好用的自然会被顶上来。发布后可在详情页或卡片菜单里编辑、下架。

隐藏笔记

写笔记时勾上“隐藏”,这篇就只存在于你自己的账号里:不进列表、不进搜索、不上首页精选,也不会出现在任何公开的页面,链接发给别人同样打不开。

适合放密码、草稿、日记这类只给自己看的内容;想公开,去“发布”打开它,把“隐藏”的勾去掉再保存,之后编辑会默认保持原状态,不会悄悄变回公开。

不想公开、只想临时给人看:点“分享”生成一条带密码和有效期的链接,到期自动失效,你也能随时撤销。

数据安全

你的内容会同时保存在多个副本上,系统定期做备份与完整性校验,再配合异地容灾机制:就算某台机器出问题,数据也不会丢,可以长期放心存放;特别重要的资料,仍建议你另外再留一份备份。

技术

全站跑在容器化、模块化的现代架构上,更新、部署、回滚都很快,扩展性和稳定性都按长期运营的标准来设计(Built for reliability, designed to scale)。

理念

这个网站最早只是一个人的笔记仓库,后来慢慢长成现在的知识中枢。设计上很克制——没有广告、没有追踪、没有推荐算法,只是干干净净地存放一些东西;既然做好了,就公开出来,万一有人用得上呢。

原则

不做大而全,不做平台梦,保持简单、保持克制、保持好奇。所有内容都由用户贡献、由用户维护:不会突然冒出付费墙,不会在角落塞广告位,也不会把你的数据卖给第三方。

更多

产品会持续迭代,站内日志页记录着每一次改动,改了什么都有迹可循;想了解这个站是怎么一步步走到今天的,翻翻日志就能看到来龙去脉。

举报

如果在这里看到涉嫌违规的内容,点对应卡片右侧的“举报”按钮就能提交,我们会尽快核实处理;也谢谢你花一点时间,一起把这里维护干净。

趋势

// 点击导航加载发现
归档
// 归档为空
最近浏览
// 暂无浏览记录
发布
// 加载中...
用户发布
// 加载中...
用户管理
// 加载中...
访问统计
// 加载中...
内容审核
// 加载中...
个人信息
// 加载中...
返回首页

selfdb:把整个Python程序变成可查询数据库的魔法库

other

selfdb 是一个将 Python 程序运行时状态自动暴露为 SQL 可查询数据库的开发工具,让你用 SQL 直接查询内存中的对象、函数调用和变量。

痛点:调试和观测 Python 程序为何如此痛苦

在开发 Python 应用时,我们经常面临这样的困境:

  • 调试复杂状态:当程序运行到某个分支时,你想知道当前所有模块的全局变量、某个对象的属性、甚至最近几次函数调用的参数——但只能靠 print 或 pdb 手动断点,效率低下。
  • 事后分析:程序崩溃后,你想复盘“当时发生了什么”,但日志不够详细,回放困难。
  • 性能分析:你想知道某个函数被调用了多少次、平均耗时多少,通常需要引入 cProfile 或手动埋点。
  • 动态数据探索:你希望像操作数据库一样,用 SELECT 和 JOIN 去探索程序内部的数据关系,但 Python 对象图是任意复杂的,没有统一查询接口。

传统方案要么是侵入式埋点(污染业务代码),要么是外部调试器(无法访问运行时上下文),要么是日志分析(丢失对象结构)。selfdb 提出一个全新的思路:把整个 Python 进程变成一台数据库服务器,你可以在程序运行的同时,用 SQL 查询它的内部状态。

selfdb 是什么

selfdb 是一个纯 Python 库,它通过 sys.settrace 钩子自动捕获程序执行过程中的所有帧(frame)、局部变量、全局变量、函数调用和返回值,并将它们组织成一张张关系表。然后,它启动一个内置的 SQLite 虚拟数据库(通过 sqlite3 的虚拟表机制),让外部客户端(如 sqlite3 命令行、Python sqlite3 模块、甚至其他语言的 SQLite 驱动)直接连接并查询这些表。

简单说:你的程序运行到一半,你可以用 SQL 去查询它现在的内存状态。

快速上手

安装

bash
pip install selfdb

最小示例:查询全局变量

python
import selfdb
import threading
import time

启动 selfdb,监听在本地 12345 端口(默认)

selfdb.start(port=12345)

程序正常运行

counter = 0
def worker():
global counter
for i in range(100):
counter += 1
time.sleep(0.01)

threads = [threading.Thread(target=worker) for _ in range(5)]
for t in threads:
t.start()

保持程序运行,等待外部查询

selfdb.wait() # 阻塞,直到 Ctrl+C

在另一个终端,用任意 SQLite 客户端连接:

bash
sqlite3 selfdb.db

或者通过 Python 连接:

python
import sqlite3
conn = sqlite3.connect('selfdb.db')

查看有哪些表

print(conn.execute("SELECT name FROM sqlite_master WHERE type='table'").fetchall())

查询全局变量 counter 的当前值

rows = conn.execute("SELECT * FROM globals WHERE name='counter'").fetchall()
print(rows)

你会发现 globals 表中有当前所有全局变量的名称、类型和值。更神奇的是,你可以实时查询——每次 SELECT 都会获取最新状态。

查询函数调用历史

selfdb 会自动记录每次函数调用的参数和返回值,存到 calls 表:

sql
SELECT function_name, args, return_value, duration_ms
FROM calls
ORDER BY timestamp DESC
LIMIT 10;

你可以看到最近 10 次函数调用的完整记录,包括参数值、返回值和耗时。这对于调试性能瓶颈和异常流程非常有用。

查询局部变量和帧信息

selfdb 还记录了每个活动线程的调用栈(stack frames)。你可以查询 frames 表:

sql
SELECT thread_id, filename, lineno, function, locals_json
FROM frames
WHERE thread_id = 5;

locals_json 是该帧的所有局部变量序列化后的 JSON 字符串。这样,你可以看到某个线程当前执行到哪一行,局部变量是什么。

核心亮点:深入技术细节

1. 基于 sys.settrace 的零侵入捕获

selfdb 利用 Python 的追踪钩子(sys.settrace)在每次函数调用、行执行、返回时触发回调。它不修改你的源代码,也不要求你显式地记录任何数据。你只需要 import selfdb; selfdb.start(),剩下的自动完成。

需要注意的是,sys.settrace 本身会带来一定的性能开销(通常 20%-50%),所以 selfdb 更适合开发调试和测试环境,不适合生产环境长期开启。但它的设计允许你通过环境变量或命令行参数动态开启/关闭,例如:

bash
SELFDB_ENABLED=1 python my_app.py

2. 虚拟表:SQLite 与 Python 对象的桥梁

selfdb 没有把数据复制到 SQLite 文件,而是通过 SQLite 的虚拟表机制(sqlite3 模块中的 create_module)动态生成查询结果。每次你执行 SELECT,它都会实时从 Python 的内存中提取数据并返回。这意味着:

  • 数据永远是最新的:你看到的就是程序此刻的状态。
  • 无持久化开销:不需要写文件,不占用磁盘。
  • 支持复杂 SQL:你可以对查询结果进行 WHERE、JOIN、GROUP BY 等操作,因为虚拟表的行为和普通表一样。

3. 支持多线程和异步

selfdb 能正确区分不同线程的帧和局部变量。对于 asyncio 协程,它也能捕获事件循环中的任务状态(通过钩住 asyncio.Task 的创建和切换)。

4. 安全性和访问控制

默认只监听 127.0.0.1,避免远程访问风险。你可以通过 selfdb.start(host='0.0.0.0') 开启远程,但需要自己加认证(建议通过 SSH 隧道)。

5. 可扩展的表结构

除了内置的 globals、locals、frames、calls 表,selfdb 还提供 objects 表,让你按类名查询所有实例:

sql
SELECT class_name, id, repr, attributes_json
FROM objects
WHERE class_name = 'MyClass';

这会遍历 gc.get_objects() 找到所有 MyClass 的实例,并序列化它们的属性。

适用场景

  1. 复杂算法调试:比如图算法、动态规划,你想在每一步检查中间状态,用 SQL 比用 print 更灵活。
  2. Web 服务开发:在 Flask/Django 开发中,你可以开启 selfdb,然后通过 SQL 查询当前请求的上下文、数据库连接池状态、缓存命中率等。
  3. 数据分析脚本:你在 Jupyter 中运行长任务,想中途查看某个变量的分布,直接用 SQL 查询。
  4. 教学演示:向学生展示 Python 程序内部执行过程,用 SQL 查询帧和变量,直观且有趣。
  5. 自动化测试:在测试框架中,你可以用 selfdb 断言某个函数被调用了多少次、参数是否正确,而不用 mock。

与其他工具对比

工具 定位 与 selfdb 的区别
pdb/ipdb 交互式调试器 需要手动打断点,只能查看当前帧,不能跨线程/跨时间查询。selfdb 提供全局、实时的 SQL 接口。
py-spy 采样性能分析器 只给出 CPU 火焰图,无法查询变量值。selfdb 能给出具体数据。
tracemalloc 内存跟踪 只关注内存分配,不提供业务对象状态。
logging 日志记录 需要手动埋点,且日志是文本流,无法结构化查询。selfdb 自动捕获所有调用和变量。
django-debug-toolbar Web 调试面板 只适用于 Django,且只显示 SQL 查询和请求信息,不能查询任意 Python 对象。
ipython 的 %debug 事后调试 只能在异常后进入,不能实时查询。

selfdb 的核心差异化在于:它把调试从“断点思维”转变为“数据库思维”。你不再需要关心“停在哪一行”,而是可以随时问“现在全局有哪些对象?它们之间的关系是什么?”

局限性与注意事项

  • 性能开销:开启追踪后,程序运行速度会明显下降,不适合生产环境。
  • 序列化限制:某些对象(如生成器、socket、线程锁)无法被序列化为 JSON,selfdb 会用其 repr 字符串代替。
  • 安全性:暴露了程序内部所有数据,切勿在不可信网络下开启远程连接。
  • Python 版本:目前支持 CPython 3.7+,不兼容 PyPy 或 Jython(因为 sys.settrace 行为差异)。

总结

selfdb 是一个极具创意的开发工具,它模糊了“程序运行”和“数据库查询”的边界。虽然它可能不会成为生产环境中的常驻工具,但在开发、调试、测试和教学场景中,它提供了一种全新的、高效的交互方式。如果你厌倦了 print 和断点调试,不妨试试用 SQL 来“审视”你的程序。

项目链接:https://github.com/fzakaria/selfdb

相似推荐
Surge把《Refactoring UI》变成可执行的代码:一个让AI自动遵循设计原则的Claude Skill腾讯WeMM-Embedding:统一多模态嵌入模型,开启跨模态检索新范式hello-sdd:从零掌握规格驱动开发的实战教程孙式写作心法:从白月光之痛蒸馏出的互联网嘴替圣经simplify-codebase:用数学证明的方式安全消除代码库中的意外复杂度
编写使用方法
Markdown 格式 · Ctrl+Enter 确定
0 字新建笔记
欢迎回来
登录你的墨穗笔记账户
忘记密码?
还没有账户?立即注册
创建账户
注册你的专属墨穗笔记
已有账户?去登录
找回密码
输入注册邮箱获取验证码
返回登录
请输入图片中的验证码以继续注册
加载中...
取消
新建收藏
手动添加你喜欢的内容
取消
编辑头像与昵称
上传新头像或修改你的显示昵称
支持 JPG/PNG,最大 2MB
取消

问题反馈

隐私提醒

取消
编辑工具
受控分享
为这篇笔记生成限时 / 带密码的临时链接
关闭