My thought was to get rid of how users are constantly using seek(0)
to reset the text file reading.
So instead I've tried to create a MyReader
that's an collections.Iterator
and then using .reset()
to replace seek(0)
and then it continues from where it last yielded by retaining a self.iterable
object.
class MyReader(collections.Iterator):
def __init__(self, filename):
self.filename = filename
self.iterable = self.__iterate__()
def __iterate__(self):
with open(self.filename) as fin:
for line in fin:
yield line.strip()
def __iter__(self):
for line in self.iterable:
yield line
def __next__(self):
return next(self.iterable)
def reset(self):
self.iterable = self.__iterate__()
The usage would be something like:
$ cat english.txt
abc
def
ghi
jkl
$ python
>>> data = MyReader('english.txt')
>>> print(next(data))
abc
>>> print(next(data))
def
>>> data.reset()
>>> print(next(data))
abc
My question is does this already exist in Python-verse somewhere? Esp. if there's already a native object that does something like this, I would like to avoid reinventing the wheel =)
If it doesn't exist? Does the object look a little unpythonic? Since it says it's an iterator but the true Iterator is actually the self.iterable
and the other functions are wrapping around it to do "resets".
I think it depends on what is your real situation. Let's say if you just want to get rid of file.seek(0)
, it can be simple:
class MyReader:
def __init__(self, filename, mode="r"):
self.file = open(filename, mode)
def __enter__(self):
return self
def __exit__(self, exc_type, exc_value, traceback):
self.close()
def __iter__(self):
self.file.seek(0)
for line in self.file:
yield line.strip()
def close(self):
self.file.close()
You can even use it like a normal context manager:
with MyReader("a.txt") as a:
for line in a:
print(line)
for line in a:
print(line)
output:
sdfas
asdf
asd
fas
df
asd
f
sdfas
asdf
asd
fas
df
asd
f