在打开的文件上进行 .seek 的优雅方式
Elegant way to .seek on an open file
我不止一次遇到过这个问题,当你在 python 中打开一个文件时使用 with open
以小字节读取它,一旦你读取了字节,如果在下一行你读了更多的字节,它从你上次调用中断的地方开始。例如:
def read_it(filename):
with open(filename, "rb") as f:
print f.read(4)
print f.read(4)
print f.read(4)
print f.read(4)
read_it("test.rtf")
#<= {\rt
#<= f1\a
#<= nsi\
#<= ansi
这个问题的解决方法是在每次读取后添加.seek(0)
从头开始:
def read_it(filename):
with open(filename, "rb") as f:
print f.read(4)
f.seek(0)
print f.read(4)
f.seek(0)
print f.read(4)
f.seek(0)
print f.read(4)
read_it("test.rtf")
#<= {\rt
#<= {\rt
#<= {\rt
#<= {\rt
但是,如您所见,多次调用 .seek
非常难看。我正在寻找一种更优雅的方式来在每次读取后返回 0。这可能吗?
如前所述,这是 python2,python3 中也有同样的问题:
Python 3.8.8 (tags/v3.8.8:024d805, Feb 19 2021, 13:18:16) [MSC v.1928 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> with open("test.rtf", "rb") as f:
... print(f.read(4))
... print(f.read(4))
... print(f.read(4))
...
b'{\rt'
b'f1\a'
b'nsi\'
>>>
我很快想到了这个:
class Rewinder:
def __init__(self, fname):
self.fname = fname
self.fd = None
def __enter__(self):
self.fd = open(self.fname)
return self
def __exit__(self, exc_type, exc_val, traceback):
self.fd.close()
self.fd = None
def read(self, size=-1):
try:
return self.fd.read(size)
finally:
self.fd.seek(0)
with Rewinder('test.txt') as f:
print(f.read(4))
print(f.read(4))
print(f.read(4))
这是您要找的吗?
我不止一次遇到过这个问题,当你在 python 中打开一个文件时使用 with open
以小字节读取它,一旦你读取了字节,如果在下一行你读了更多的字节,它从你上次调用中断的地方开始。例如:
def read_it(filename):
with open(filename, "rb") as f:
print f.read(4)
print f.read(4)
print f.read(4)
print f.read(4)
read_it("test.rtf")
#<= {\rt
#<= f1\a
#<= nsi\
#<= ansi
这个问题的解决方法是在每次读取后添加.seek(0)
从头开始:
def read_it(filename):
with open(filename, "rb") as f:
print f.read(4)
f.seek(0)
print f.read(4)
f.seek(0)
print f.read(4)
f.seek(0)
print f.read(4)
read_it("test.rtf")
#<= {\rt
#<= {\rt
#<= {\rt
#<= {\rt
但是,如您所见,多次调用 .seek
非常难看。我正在寻找一种更优雅的方式来在每次读取后返回 0。这可能吗?
如前所述,这是 python2,python3 中也有同样的问题:
Python 3.8.8 (tags/v3.8.8:024d805, Feb 19 2021, 13:18:16) [MSC v.1928 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> with open("test.rtf", "rb") as f:
... print(f.read(4))
... print(f.read(4))
... print(f.read(4))
...
b'{\rt'
b'f1\a'
b'nsi\'
>>>
我很快想到了这个:
class Rewinder:
def __init__(self, fname):
self.fname = fname
self.fd = None
def __enter__(self):
self.fd = open(self.fname)
return self
def __exit__(self, exc_type, exc_val, traceback):
self.fd.close()
self.fd = None
def read(self, size=-1):
try:
return self.fd.read(size)
finally:
self.fd.seek(0)
with Rewinder('test.txt') as f:
print(f.read(4))
print(f.read(4))
print(f.read(4))
这是您要找的吗?