快速修改Python源码时.pyc缓存未失效问题咨询
Python频繁修改源码却运行旧代码的问题分析与解决
这不是Python的Bug,问题根源在于Python默认使用秒级精度的文件时间戳来判断.pyc字节码文件是否过期。你的脚本每隔0.3秒修改一次b.py,同一秒内的多次修改会被识别为相同时间戳,Python认为字节码仍有效,不会重新编译,所以重复运行旧代码。
以下是除python3 -B之外的解决办法:
1. 启用基于哈希的字节码验证(修复你之前的无效问题)
你之前用--check-hash-based-pycs always无效,大概率是因为残留了旧的时间戳式.pyc文件。按以下步骤操作:
- 先删除所有
__pycache__目录:rm -rf __pycache__/ - 再用哈希验证模式运行脚本:
哈希验证会直接对比源码内容的哈希值,而非时间戳,能精准检测任何代码修改,不受系统时间精度限制。python3 --check-hash-based-pycs always a.py
2. 在代码中强制重新加载模块
修改a.py,每次运行时动态重新加载b模块,跳过字节码缓存:
import importlib import b # 强制重新加载b模块,读取最新源码 importlib.reload(b) print(b.i)
3. 通过环境变量禁用字节码生成
设置PYTHONDONTWRITEBYTECODE环境变量,让Python完全不生成.pyc文件,每次直接读取源码:
- 临时生效(当前终端会话):
export PYTHONDONTWRITEBYTECODE=1 python3 a.py - 永久生效(添加到shell配置文件):
把export PYTHONDONTWRITEBYTECODE=1写入你的~/.bashrc或~/.zshrc,重启终端后生效。
4. 每次运行前删除对应字节码文件
在c.sh中添加删除b.py对应.pyc文件的步骤,确保每次运行都重新编译:
for i in {1..20}; do echo "i = $i" > b.py sleep 0.3 echo -n "$i " # 删除b.py对应的字节码文件,替换为你的Python版本后缀 rm -f __pycache__/b.cpython-313.pyc python3 a.py done
注意:.pyc文件名格式为{模块名}.cpython-{Python版本号}.pyc,比如Python 3.13对应的就是b.cpython-313.pyc。
内容的提问来源于stack exchange,提问作者Eric Stdlib




