python 3的更改之一是删除了在普通文本模式下从文件末尾查找的功能。什么是普遍接受的替代方案?
例如在python 2.7中,我将输入file.seek(-3,2)
我已经读过一些关于他们为什么这样做的信息,所以请不要仅仅链接到PEP。我知道使用'rb'可以搜索,但这会使我的文本文件读取格式错误。
最佳答案
在Python 2中,文件数据在读取时没有被解码。向后搜索和多字节编码混合得不好(您不知道下一个字符将从哪里开始),这就是为什么Python 3禁用了它。
您仍然可以通过TextIOBase.buffer
attribute在基础缓冲区对象上进行搜索,但是随后您必须重新附加新的TextIOBase
包装器,因为当前包装器将不再知道其位置:
import io
file.buffer.seek(-3, 2)
file = io.TextIOWrapper(
file.buffer, encoding=file.encoding, errors=file.errors,
newline=file.newlines)
我已经将所有编码和行处理信息复制到了
io.TextIOWrapper()
object。请注意,对于UTF-16,UTF-32,UTF-8和其他多字节编解码器,此解码可能会中断。
演示:
>>> import io
>>> with open('demo.txt', 'w') as out:
... out.write('Demonstration\nfor seeking from the end')
...
38
>>> with open('demo.txt') as inf:
... print(inf.readline())
... inf.buffer.seek(-3, 2)
... inf = io.TextIOWrapper(inf.buffer)
... print(inf.readline())
...
Demonstration
35
end
您可以将其包装在实用程序函数中:
import io
def textio_seek(fobj, amount, whence=0):
fobj.buffer.seek(amount, whence)
return io.TextIOWrapper(
fobj.buffer, encoding=fobj.encoding, errors=fobj.errors,
newline=fobj.newlines)
并将其用作:
with open(somefile) as file:
# ...
file = textio_seek(file, -2, 3)
# ...
将文件对象用作上下文管理器仍然有效,因为原始文件对象引用仍附加到原始文件缓冲区对象,因此仍可以用于关闭文件。