Lazy file reader that yields one line at a time

Question:

I want to build a class that can be used like this:

d = Data(file_name)
line = next(d)

# or

for line in d:
  print(line)

I have this class:

@dataclass
class Data:
    file_name: str
    data: IO = field(default=None)

    def __post_init__(self):
        self._data = open(self.file_name)

    def __enter__(self):
        return self

    def read_lines(self):
        for line in self._data:
            yield line

    def __next__(self):
        for line in self._data:
            yield line

    def __exit__(self, exc_type, exc_val, exc_tb):
        if self.data:
            self.data.close()

If I use this code then it works fine:

with self._data as data:
    for line in data.read_lines():
        print(line)

but when trying to use next then I print generator objects instead of the file lines.

with self._data as data:
    while line := next(data):
       print(line)

How can I successfully use the next method?

Asked By: dearn44

||

Answers:

The file itself is an iterator. The only thing your __next__ function has to do is call next on it.

def __next__(self):
    return next(self._data)
Answered By: chepner
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.