SQLite WITHOUT ROWID 主键:同样的建表字段,为什么空值规则变了 主键写在纸上,约束还要看表的类型把普通表的建表语句末尾加上 WITHOUT ROWID,字段名称没有变化,旧数据却可能导入失败。最容易忽略的原因是主键中的空值:SQLite 为兼容历史行为,普通、非 STRICT 的... yunqueblog/ 技术教程/ 2026-10-02/ 3 阅读
Python find_spec 探测子模块:还没导入它,为什么父包代码已经执行了 插件发现代码只是想判断 package.feature 是否存在,调用 find_spec 后却看到包的初始化日志。函数没有执行目标子模块,不代表整条查找路径完全没有导入行为。名称包含点号时,它需要导入父模块来获得子... yunqueblog/ 技术教程/ 2026-10-02/ 3 阅读
Python finalize 清理回调:已经删掉对象,为什么绑定方法还把它留住了 为对象注册销毁时的清理动作,最顺手的写法是 weakref.finalize(obj, obj.close)。但删掉 obj 后,close 迟迟没有执行。终结器虽然通过弱引用观察目标,它保存的回调却是绑定方法;绑定... yunqueblog/ 技术教程/ 2026-10-02/ 3 阅读
Python 字典的相等键:True、1 和 1.0,为什么最终只剩一个位置 汇总几类配置时,用 True 表示开关,用整数一表示编号,用浮点一表示测量值,觉得三种类型应该占三个字典位置。实际逐个写入后长度却只有一,最后的文字覆盖了前两份。原因是普通字典采用键的相等语义,这几个内置数值对象彼此... yunqueblog/ 技术教程/ 2026-10-02/ 3 阅读
Python warnings 规则顺序:先设置 error,为什么后来的一条 ignore 让测试通过了 测试启动时把自家组件的告警设成错误,希望升级依赖后及时失败。后来公共初始化代码又加了一条忽略所有告警,原本该失败的样本突然通过。过滤系统不会把匹配规则全部执行一遍,也不会自动选择类别最具体的规则;排在前面的第一条匹配... yunqueblog/ 技术教程/ 2026-10-02/ 3 阅读
Python 临时缓冲落盘:还没达到 max_size,为什么 fileno 已经创建了文件 一个小文件处理器使用 SpooledTemporaryFile,希望内容较小时留在内存,超过阈值再使用临时文件。数据明明只有三个字节,接入某个库后却发生了落盘。原因可能是对方请求了 fileno:底层需要操作系统文件... yunqueblog/ 技术教程/ 2026-10-02/ 3 阅读
Python shorten 的空白折叠:文字还没超长,为什么换行已经不见了 给日志列表生成一行预览时,原文只有十几个字符,宽度设成一百,换行和连续空格却仍然消失。检查长度没有发现截断,容易误以为数据在读入时损坏。实际变化可能发生在 textwrap.shorten:它先整理空白,再判断是否需... yunqueblog/ 技术教程/ 2026-10-02/ 4 阅读
Python 日志级别已关闭:debug 没有输出,昂贵函数为什么仍然被调用 服务把日志级别设为 WARNING,调试输出已经消失,生成大型诊断摘要的函数却仍然运行。代码写的是 logger.debug("summary=%s", build_summary()),看起来采用了延迟格式化。问题... yunqueblog/ 技术教程/ 2026-10-02/ 3 阅读
Python dataclasses.replace:只改数量,为什么手动改过的派生字段又被重算 一条数据类记录里,单价和数量用于构造对象,总额在初始化后计算。调试时手动修正过总额,随后用 dataclasses.replace 修改数量,却发现新对象没有保留那份手动值。这不是 replace 漏拷贝,而是它通过... yunqueblog/ 技术教程/ 2026-10-02/ 3 阅读
Python 正则搜索起点:pos 已经移到中间,为什么 ^ 仍不匹配那里 从日志中找到正文起点后,把这个位置传给编译后正则的 search,以为表达式里的 ^ 就会把那里当开头。结果普通文字能找到,加了行首锚点却返回 None。pos 限制从哪里开始尝试匹配,没有把原字符串切成一段新字符串... yunqueblog/ 技术教程/ 2026-10-02/ 3 阅读