FAQ
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

Search Discussions

  • Cameron Simpson at Oct 15, 2010 at 3:45 am

    On 14Oct2010 20:11, Steve Howell wrote:
    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.
    This sounds like the "yield from" proposal that had discussion some
    months ago. Your above idiom would become:

    yield from g()

    See PEP 380:
    http://www.python.org/dev/peps/pep-0380/
    Short answer, not available yet.

    A Google search on:

    python pep "yield from"

    found some implementations at activestate, such as this:

    http://code.activestate.com/recipes/577153-yet-another-python-implementation-of-pep-380-yield/

    which lets you decorate an existing generator so that you can write:

    yield _from(gen())

    where gen() is the decorated generator.

    Cheers,
    --
    Cameron Simpson <cs at zip.com.au> DoD#743
    http://www.cskk.ezoshosting.com/cs/

    What I want is Facts. Teach these boys and girls nothing but Facts. Facts
    alone are wanted in life. Plant nothing else, and root out everything else.
    - Charles Dickens John Huffam 1812-1870 Hard Times [1854]
  • Steve Howell at Oct 15, 2010 at 5:02 am

    On Oct 14, 8:45?pm, Cameron Simpson wrote:
    On 14Oct2010 20:11, Steve Howell wrote:
    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.
    This sounds like the "yield from" proposal that had discussion some
    months ago. Your above idiom would become:

    ? yield from g()

    See PEP 380:
    ?http://www.python.org/dev/peps/pep-0380/
    Short answer, not available yet.
    Very interesting, thanks.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
grouppython-list @
categoriespython
postedOct 15, '10 at 3:11a
activeOct 15, '10 at 5:02a
posts3
users2
websitepython.org

2 users in discussion

Steve Howell: 2 posts Cameron Simpson: 1 post

People

Translate

site design / logo © 2022 Grokbase