seek()和tell()用于控制文件指针位置:tell()返回当前字节偏移量,seek(offset, whence)按指定参考点移动指针;文本模式下whence=1/2可能报错,建议二进制模式操作。

Python中文件指针的位置控制是读写文件的关键,seek()和tell()是两个最常用、也最容易被误解的函数。它们不负责读写数据,只管理“当前读写位置”——就像用手指在书页上滑动,告诉Python“接下来从这里开始读或写”。
tell():知道“我在哪”
tell()返回当前文件指针相对于文件开头的字节偏移量(整数)。它不改变指针位置,纯属“查询”。无论文件是以文本模式还是二进制模式打开,它都返回字节数(注意:文本模式下中文字符可能占多个字节,不能简单等同于字符数)。
- 刚打开文件时,tell()通常返回0(除非用'r+'且文件非空,但指针仍在开头)
- 每次调用read()、readline()或write()后,指针会自动移动,tell()能立刻反映新位置
- 对已关闭的文件调用tell()会抛出ValueError
seek():主动“跳到哪”
seek(offset, whence=0)把指针移到指定位置。offset是偏移量,whence决定参考点:
- whence=0(默认):从文件开头算起,seek(10) → 指针停在第10个字节处(索引从0开始)
- whence=1:从当前位置算起,seek(-5, 1) → 向前退5字节(仅支持二进制模式)
- whence=2:从文件末尾算起,seek(-10, 2) → 末尾倒数第10字节(常用于读取日志尾部,也仅二进制模式安全)
⚠️ 文本模式下,whence=1和whence=2可能引发UnsupportedOperation,尤其含中文或换行符时;稳妥做法是统一用二进制模式处理指针跳转,再按需解码。
立即学习“Python免费学习笔记(深入)”;
配合使用:边读边定位的典型场景
比如处理固定长度记录的日志文件(每行40字节),想跳过前100条直接读第101条:
- 用seek(100 * 40)直接定位到第101条起始位置
- 用read(40)读取该条记录
- 中间可穿插tell()验证位置是否准确,避免因编码或换行符导致的偏移误差
又如“读一部分→处理→回退重读”流程:pos = f.tell(); data = f.read(100); f.seek(pos),就能重复利用同一段内容。
注意事项与常见坑
- 文本文件慎用seek()跳转到非行首位置,可能导致解码错误(如UTF-8中截断多字节字符)
- 写入模式('w')下,seek()后写入会覆盖原有内容,而非插入;若需插入,应先读全内容,修改后再整体写入
- 调用seek()后立即read(),若指针已在末尾,将返回空字符串;可用tell()提前检查
- 管道、终端等非普通文件对象不支持seek()和tell(),会报io.UnsupportedOperation










