科技 · 实用指南
Python 报 WinError 32?重试前先证明谁持有文件句柄
路径是证据,不是所有者。修改权限、sleep 或结束进程前,先追踪仍存活的 Python 对象、子进程、目录上下文与外部句柄。

WinError 32 不是要求 Python 获得更高权限,而是请求的 Windows 访问或共享模式与存活句柄冲突。所有者可能是当前对象、子进程、目录上下文或另一程序。
固定操作和路径,从当前进程向外证明所有者,通过受支持生命周期关闭一个所有者,再重放真实工作负载。不要强关句柄,也不要把一次侥幸通过的 sleep 当修复。
1. 固定精确操作与路径
记录完整回溯、winerror、源与目标路径、PID、线程、启动器,以及失败的是删除、重命名、替换还是轮转。实验前保留源文件字节。
在真实 watcher、worker、notebook、服务或日志轮转路径中复现一次;不要先提权、改权限、sleep、关闭杀毒或无限重试。
2. 证明 Python 是否仍持有句柄
从失败调用向后审计每个 open、上下文管理器、迭代器、ZIP、图像、PDF、工作簿、映射文件与日志 handler。路径字符串没有 close;库对象才拥有句柄。
把变更移到 with 之外,或在 finally 中调用库文档规定的 close 或 shutdown。惰性读取器返回元数据后也可能继续持有文件。
3. 检查子进程、目录与重复所有者
记录仍存活的 subprocess、worker、pool 与继承资源。父变量消失后,子进程仍可能保留同一个文件对象;先 join 或关闭所有者并证明它已退出。
重命名或删除目录时记录父子进程的当前工作目录,并区分重复打开与跨进程复制句柄。
4. 不强关句柄地识别外部所有者
若当前进程及子进程干净,用 Microsoft Handle 或 Process Explorer 搜索精确路径,记录进程名、PID、账户与时间。常见所有者包括编辑器、下载器、同步、索引、扫描和日志收集进程。
通过应用支持的方式停止或重配所有者。不要把 Handle -c 当日常修复;Microsoft 明确警告强制关闭句柄可能造成不稳定。
5. 只修一个所有者并重放工作负载
实施最小修复:退出上下文、关闭库对象、join 子进程、统一日志轮转所有者,或等待已测量的短暂外部操作。保留原字节与回滚路径。
连续两次重放原工作负载;操作必须成功,目标字节与元数据正确,完成后无残留所有者,下一轮转、同步或 worker 周期不得复发。
