Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible and advisable to subclass a generator function?

I frequently use a generator that returns a certain class. What I'd like to do is subclass the generator class so that I can use methods on it that are appropriate for generators that yield instances of that class. For example, one of the things I'd like to do is have a method that returns a generator that filters the base generator.

I want to do something like this:

class Clothes(object):
    def __init__(self, generator):
        self.generator = generator

    def get_red(self):
        return (c for c in self.generator if c.color=="red")

    def get_hats(self):
        return (c for c in self.generator if c.headgear)

The clothes class I want to treat as a collection of clothes. The reason I'm not subclassing a collection is that I rarely want to use the whole collection of clothes as is, and usually just need to filter it further. However, I often need the various filtered collections of clothes. If possible, I'd like Clothes to be a generator itself, as that's how I intend to use it, but I get an error when trying to subclass types.GeneratorType.

like image 278
cammil Avatar asked Dec 04 '22 16:12

cammil


1 Answers

types.GeneratorType 

is defined as:

def _g():
    yield 1
GeneratorType = type(_g())

as you see, it is not a regular class.

Now, what makes a generator special? Not much. To make use of the generator protocol, all one has to do is to implement the iterator protocol. There is a nice shortcut: you get the next() for free, when your __iter__ is a generator. And that's exactly how collections.Iterable is defined:

class Iterable(metaclass=ABCMeta):

    @abstractmethod
    def __iter__(self):
        while False:
            yield None

    @classmethod
    def __subclasshook__(cls, C):
        if cls is Iterable:
            if any("__iter__" in B.__dict__ for B in C.__mro__):
                return True
        return NotImplemented

So, just use that to build your generator.

like image 75
ch3ka Avatar answered Jan 31 '23 23:01

ch3ka