Yield n lines from a Generator class in Python

python generator class
python generator example
python yield
python generator next
python generator expression
python generator to list
python generator send
python generator vs iterator

I want to print n lines from a file everytime a Generator class is called.

I have tried the following:

class FileReader:
    def __init__(self, file):
        with open(file, 'r') as fin:
            read_file = fin.read()

            # gen-comp yielding stripped lines
            lines = (line.strip() for line in read_file)
            print(lines)

This simply returns all the lines.


You could implement a __call__ method like,

import sys
from itertools import islice

class FileReader:
    def __init__(self, fname, len=3):
        self.fname = fname
        self._len = len

    def __enter__(self):
        self.fd = open(self.fname, 'r')
        return self

    def __call__(self):
        return list(islice(self.fd, self._len))

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


with FileReader(sys.argv[1]) as f:
    print(f())
    print(f())

How to Use Generators and yield in Python – Real Python, In this step-by-step tutorial, you'll learn about generators and yielding in Python. state every time it's called, but the function is too small to justify creating its own class. Using return will result in the first line of the file only. 1 file_name = "techcrunch.csv" 2 lines = (line for line in open (file_name)) 3 list_line = (s. rstrip (). split (",") for s in lines) 4 cols = next (list_line) To sum this up, you first create a generator expression lines to yield each line in a file.


I am not that familiar with class programing or generators but the following i drafted seems to fill your criteria to print x number of lines each time the object is called

class FileReader:
    def __init__(self, file, num_lines=10):
        fin = open(file, 'r')
        self.file_handle = fin
        self.num_lines = num_lines

    def __next__(self):
        for i in range(self.num_lines):
            yield self.file_handle.readline().strip()

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

    def __str__(self):
        return "".join(list(next(self)))

myfile = FileReader('query4.txt', 2)
print(myfile)
print(myfile)

INPUT FILE

this is some data
this is other data
data is fun
data is weird
this is the 5th line

As you have stripped new line chars in your original program i have done the same so assume you want to concat the X lines together. If thats not the case then just remove the .strip()

OUTPUT

this is some datathis is other data
data is fundata is weird

Generators, 1 # Using the generator pattern (an iterable) 2 class firstn(object): 3 def 1 # a generator that yields items instead of returning a list 2 def firstn(n): 3 num Note that both lines are identical in form, but the one using range is  def PowTwoGen(max=0): n = 0 while n < max: yield 2 ** n n += 1. Since generators keep track of details automatically, the implementation was concise and much cleaner. 2. Memory Efficient. A normal function to return a sequence will create the entire sequence in memory before returning the result.


Your file object is already a generator.

class FileReader:
    def __init__(self, file, lines=3):
        self.fd = open(file, 'r')
        self.lines = lines

    def __call__(self):
        for i in range(self.lines):
            print(self.fd.readline())

This will just print empty lines when you reach the end of the file, if that's not what you want then you can try:

import os

class FileReader:
    def __init__(self, file, lines=3):
        self.fd = open(file, 'r')
        self.lines = lines
        self.end = self.fd.seek(0, os.SEEK_END)
        self.fd.seek(0)

    def __call__(self):
        for i in range(self.lines):
            if self.fd.tell() == self.end:
                print('Reached EOF')
                return
            print(self.fd.readline())

Python yield, Generators and Generator Expressions, In this tutorial, you'll learn how to create iterations easily using Python generators, how it is different 1 9 36 100 Traceback (most recent call last): File "<string>", line 15, class PowTwo: def __init__(self, max=0): self.n = 0 self.max = max def​  Generator and yield are used frequently in Python. In this article, let’s discuss some basics of generator , the benefit for generator, and how we use yield to create a generator. At the same time, we study two concepts in computer science: lazy evaluation and stream.


You say you want a generator, and so a simple solution is just to write one directly, using yield. Something like this perhaps (though it might be possible to improve the looping structure of the code):

def FileReader(filename, length):
    with open(filename, 'r') as fin:
        while True:
            group = []
            for i in range(length):
                try:
                    group.append(next(fin).strip())
                except StopIteration:
                    break
            if not group:
                break
            yield group

This then, for example, will print a list of 8 lines each time:

for g in FileReader(filename, 8):
    print(g)

Or here's an alternative that I prefer. I've knocked up an iterator building block, in the spirit of itertools, which groups up any Iterable into lists of a specified length. You can then apply this directly to a file object to do what you want:

import itertools

def group(iterable, length):
    for key,group in itertools.groupby(
                 enumerate(iterable),
                 key=lambda elem : elem[0] // length):
        yield [elem[1] for elem in group]

So this can then be used to just wrap the file object like this:

fin = open(filename, "r")
for g in group(fin, 8):
    print([e.strip() for e in g])

Note that in this case, to preserve the generality of the group function, I've omitted the strip and therefore had to do it at the end.

5. Iterators & Generators, If we use it with a file, it loops over lines of the file. class yrange: def __init__(​self, n): self.i = 0 self.n = n def __iter__(self): return self def __next__(self): if self.i Each time the yield statement is executed the function generates a new value. yield is a keyword in Python that is used to return from a function without destroying the states of its local variable and when the function is called, the execution starts from the last yield statement. Any function that contains a yield keyword is termed as generator.


Python Generators – Dataquest, Python generators are a powerful, but misunderstood tool. Use this tutorial to begin In order to get the generator function to yield its values, you need to pass it into the Furthermore, each row ends with an \n , which indicates a line break. A Python generator is a function which returns a generator iterator (just an object we can iterate over) by calling yield. yield may be called with a value, in which case that value is treated as the "generated" value.


Python Generators, A Python generator is a function that produces a sequence of results. Generators were introduced in PEP 255, together with the yield statement. generator_example_1.py def numberGenerator(n): number = 0 while number < n: yield number Thus, in the last line we send the value 5, which will be used as input by the  Yield are used in Python generators. A generator function is defined like a normal function, but whenever it needs to generate a value, it does so with the yield keyword rather than return. If the body of a def contains yield, the function automatically becomes a generator function. filter_none. edit.


Improve Your Python: 'yield' and Generators Explained, A Python generator is a function which returns a generator iterator Previously, creating something like a random number generator required a class or the first line of the generator function up to the first yield statement),  1 # Note: Python 2.x only 2 # using a non-generator 3 sum_of_first_n = sum (range (1000000)) 4 5 # using a generator 6 sum_of_first_n = sum (xrange (1000000)) Note that both lines are identical in form, but the one using range is much more expensive.