Search code examples
pythongeneratoryield

Using Yield and return a list of error


I have a piece of code (an xls parser) that does some validation on the fields and returns with yield a generator that contains every row of the xls.

Now, i have to collect validation errors in a list, and use them when the generator is exhausted.

This is a piece of code that represent the parser and a poor designed solution.

error_list = []

def gen(limit): #xls parser
    for x in range(limit):
        if x%2: #fake error contition
            error_list.append(x)
        else:
            yield(x*x) #return

is there a more pythonic way to do this? i'm not a big fan of global variables.

i'd love to keep the code as it is as much as possible but if there's no other way i'll convert the function to a classic

def gen(limit): #xls parser
    error_list = []
    results = []
    for x in range(limit):
        if x%2: #fake error contition
            error_list.append(x)
        else:
            results.append(x*x)
    return results, error_list

Solution

  • A generator function cannot return out-of-band data like this.

    I'd use a class instead, as an instance gives you something to stick such extra state:

    class XLSParser(object):
        def __init__(self, limit):
            self.error_list = []
            self.limit = limit
    
        def __iter__(self):
            for x in range(self.limit):
                if x%2: #fake error condition
                    self.error_list.append(x)
                else:
                    yield(x*x) #return
    

    and iterate over that object:

    parser = XLSParser(limit)
    for result in parser:
        # do something
    
    errors = parser.error_list