extract method with generators

2010-10-14 Thread 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
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: extract method with generators

2010-10-14 Thread Cameron Simpson
On 14Oct2010 20:11, Steve Howell showel...@yahoo.com 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 c...@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 DickensJohn Huffam   1812-1870  Hard Times [1854]
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: extract method with generators

2010-10-14 Thread Steve Howell
On Oct 14, 8:45 pm, Cameron Simpson c...@zip.com.au wrote:
 On 14Oct2010 20:11, Steve Howell showel...@yahoo.com 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.
-- 
http://mail.python.org/mailman/listinfo/python-list