Is it possible and appropriate to subclass the generator function?

I often use a generator that returns a specific class. What I would like to do is subclass the generator class so that I can use the methods on it that are suitable for the generators that give instances of this class. For example, one of the things I would like to do is 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 class of clothes that I want to consider as a collection of clothes. The reason I don’t subclass the collection is because I rarely want to use the entire clothing collection as it is, and usually just need to filter it further. However, I often need various filtered clothing collections. If possible, I would like the clothes to be a generator, as I intend to use them, but I get an error when trying to subclass types.GeneratorType.

+3
source share
3 answers

- , , , , , . yield; , , , .

types.GeneratorType . . , , itertools .

+4
types.GeneratorType 

:

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

, class.

, ? . generator protocol, , , iterator protocol. : next() , __iter__ . collections.Iterable:

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

, .

+7

, , , . PEP 289:

... , . , .

:

  • , __iter__ (, , ).
  • define get_xxx , self yield

:

class Numbers(object):

    def __iter__(self):
        for x in range(10):
            yield x

    def get_odd(self):
        for x in self:
            if x & 1:
                yield x


nums = Numbers()

for x in nums:
    print x   # 0 1 2 3...

for x in nums.get_odd():
    print x # 1 3 5...
+5
source

All Articles