Stacking generators - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: General Coding Help (https://python-forum.io/forum-8.html) +--- Thread: Stacking generators (/thread-80.html) |
Stacking generators - Ofnuts - Sep-18-2016 So I have a class where an algorithm in a method of the base class needs to iterate things that will depend on the derived class: class BaseClass(object): def __init__(self,string): self.string=string def iterateChars(self): print ','.join([c for c in self.generator()])This is easily implemented when the derived class has a simple generator: class DerivedWithSingleGenerator(BaseClass): def __init__(self,string): super(DerivedWithSingleGenerator,self).__init__(string) def generator(self): for c in '+'.join([c for c in self.string]): yield cNow, things get complicated because another derived class may require two rather different generators (and I don't really want to define different classes just for this). The best I can come up with is to have the generator expected by the parent class select one of the possible generators and iterate it: class DerivedWithComplexGenerator(BaseClass): def __init__(self,string,uc): super(DerivedWithComplexGenerator,self).__init__(string) self.uc=uc # one of the possible generators def lcGenerator(self): for c in self.string.lower(): yield c # the other possible generator def ucGenerator(self): for c in self.string.upper(): yield c # So this generator ends up iterating another generator def generator(self): gen=self.ucGenerator() if self.uc else self.lcGenerator() for c in gen: yield cSome test code: sg=DerivedWithSingleGenerator('aBcdEFg') sg.iterateChars() cgu=DerivedWithComplexGenerator('aBcdEFg',True) cgu.iterateChars() cgl=DerivedWithComplexGenerator('aBcdEFg',False) cgl.iterateChars()The code above is a bit artificial but demonstrates the problem. IRL I'm iterating strokes in Gimp paths, and in some cases re-splitting the strokes... So, the question: can you think of a better way? Can there be some unforeseen problem when a generator iterates another? I also thought about a "factory" method in the derived class to return the generator to use but it makes the simple case more complex just to support the more complex case. RE: Stacking generators - ichabod801 - Sep-18-2016 Why not just return the appropriate generator: def generator(self): if self.uc: return self.ucGenerator() else: return self.lcGenerator()Then you're not generating over a generator, you're just providing the correct generator to the original iteration. RE: Stacking generators - Ofnuts - Sep-18-2016 (Sep-18-2016, 08:21 PM)ichabod801 Wrote: Why not just return the appropriate generator: ** Slaps forehead ** Doh... In my "factory" method I was returning self.ucGenerator and not self.ucGenerator(). These parens make a huge difference... ichabod801.virtual_beers+=1 |