Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python how to turn a result of a method into generator

I have the following inheritance:

class Processor(object):
    def get_listings(self):
        """
        returns a list of data
        """
        raise NotImplemented()

    def run(self):
        for listing in get_listings():
           do_stuff(listing)

class DBProcessor(Processor):
    def get_listings(self):
        """
        return a large set of paginated data
        """
        ...
        for page in pages:
            for data in db.fetch_from_query(...):
                yield data

Although this works, this fails on len(self.get_listings()) or any other list operations.

My question is how to refactor my code that DBProcessor.get_listings can handle list operations, but also when it's iterator called it will return a generator?

like image 317
James Lin Avatar asked Apr 17 '16 22:04

James Lin


People also ask

Can you return in a generator function Python?

It uses yield instead of return keyword. So, this will return the value against the yield keyword each time it is called. However, you need to create an iterator for this function, as shown below. The generator function cannot include the return keyword.

How do you turn a function into a generator?

It is as easy as defining a normal function, but with a yield statement instead of a return statement. If a function contains at least one yield statement (it may contain other yield or return statements), it becomes a generator function. Both yield and return will return some value from a function.

What does next () do in a generator Python?

Generator Implementation in Python Above I had first created a generator function that has three yield statements and when we call this function is returns a generator which is an iterator object. We then called the next() method to retrieve elements from this object.

How do you return a yield in Python?

The Yield keyword in Python is similar to a return statement used for returning values or objects in Python. However, there is a slight difference. The yield statement returns a generator object to the one who calls the function which contains yield, instead of simply returning a value.


1 Answers

I think I got an idea:

class DBListings(object):
    def __iter__(self):
        for page in pages:
            for data in db.fetch_from_query(...):
                yield data

    def __len__(self):
        return db.get_total_from_query(...)
        """
        Or the following
        counter = 0
        for x in self:
           counter += 1
        return counter
        """

class DBProcessor(Processor):
    def get_listings(self):
        """
        return a large set of paginated data
        """
        return DBListings()

UPDATE: Just tested the above code, works.

like image 74
James Lin Avatar answered Nov 06 '22 02:11

James Lin