extract method with generators

S

Steve Howell

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
 
S

Steve Howell

| 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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top