extract method with generators

Steve Howell showell30 at yahoo.com
Thu Oct 14 23:11:24 EDT 2010


Is there a way to extract code out of a generator function f() into
g() and be able to have f() yield g()'s result without this idiom?:

  for g_result in g():
    yield g_result

It feels like a clumsy hindrance to refactoring, to have to introduce
a local variable and a loop.

Here is a program that illustrates what I'm trying to achieve--
basically, I want some kind of general mechanism to exhaust one
generator from another.

This was tested on python2.6.  The failed attempts all simply produce
the number 50 and stop.

    def unfactored():
        # toy example, obviously
        # pretend this a longer method in need of
        # extract-method
        yield 50
        for num in [100, 200]:
            yield num+1
            yield num+2
            yield num+3

    print 'Works fine:'
    for x in unfactored():
        print x
    print

    def extracted_submethod(num):
        yield num+1
        yield num+2
        yield num+3

    print 'quick test'
    for x in extracted_submethod(100):
        print x
    print

    def refactored_original_method():
        yield 50
        for num in [100, 200]:
            # naively delegate
            extracted_submethod(num)

    # the next does not do what you expect
    print 'try naive'
    for x in refactored_original_method():
        print x
    print 'DOH! that is all?'
    print

    # this feels clumsy
    def clumsy_refactored_original_method():
        yield 50
        for num in [100, 200]:
            for x in extracted_submethod(num):
                yield x

    print 'Works fine:'
    for x in clumsy_refactored_original_method():
        print x
    print

    # try to generalize and fail again
    def exhaust_subgenerator(g):
        for x in g:
            yield x

    def f():
        yield 50
        for num in [100, 200]:
            exhaust_subgenerator(extracted_submethod(num))

    print 'Try again'
    for x in f():
        print x
    print 'DOH! that is all?'
    print



More information about the Python-list mailing list