By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
458,084 Members | 1,266 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 458,084 IT Pros & Developers. It's quick & easy.

Yield in a wrapper function

P: n/a
This works exactly as you would expect::

from time import sleep
def foo(on='ABC'):
for e in list(on):
sleep(1)
yield e

When I run this on the command line It takes about 3 seconds to
complete and the first letter is shown after 1 second.
But, how do I wrap the function somewhere else::

from time import sleep
def foo(on):
for e in list(on):
sleep(1)
yield e

def wrapper(x):
if x < 0:
return foo('ABC')
else:
return foo('XYZ')

When I run this, variable three letters are shown and it takes 3
seconds for the whole thing to complete. The problem is that the whole
iteration is glogged up in the wrapper() function because the first
letter is shown after 3 seconds and then all letters are shown at the
same time.

How do I wrap functions that return iterators? ...if possible.

Nov 22 '05 #1
Share this Question
Share on Google+
4 Replies


P: n/a
pe*****@gmail.com wrote:
from*time*import*sleep
def*foo(on):
for*e*in*list(on):
Just

for e in on:
#...

is better. The list() constructor defeats much of the laziness you gain by
using a generator.
sleep(1)
yield*e

def*wrapper(x):
if*x*<*0:
return*foo('ABC')
else:
return*foo('XYZ')

When I run this, variable three letters are shown and it takes 3
seconds for the whole thing to complete. The problem is that the whole
iteration is glogged up in the wrapper() function because the first
letter is shown after 3 seconds and then all letters are shown at the
same time.

How do I wrap functions that return iterators? ...if possible.


The code you presented is OK. Your diagnosis is probably the result of a of
a misconstrued test case. Something like

for s in wrapper(1):
print s,

seems to work like you described because the text is buffered until the line
is complete. Try

for s in wrapper(1):
print s

or

import sys
for s in wrapper(1):
print s,
sys.stdout.flush() # explicitly flush the buffer

instead.

Peter


Nov 22 '05 #2

P: n/a
pe*****@gmail.com wrote:
from*time*import*sleep
def*foo(on):
for*e*in*list(on):
Just

for e in on:
#...

is better. The list() constructor defeats much of the laziness you gain by
using a generator.
sleep(1)
yield*e

def*wrapper(x):
if*x*<*0:
return*foo('ABC')
else:
return*foo('XYZ')

When I run this, variable three letters are shown and it takes 3
seconds for the whole thing to complete. The problem is that the whole
iteration is glogged up in the wrapper() function because the first
letter is shown after 3 seconds and then all letters are shown at the
same time.

How do I wrap functions that return iterators? ...if possible.


The code you presented is OK. Your diagnosis is probably the result of a of
a misconstrued test case. Something like

for s in wrapper(1):
print s,

seems to work like you described because the text is buffered until the line
is complete. Try

for s in wrapper(1):
print s

or

import sys
for s in wrapper(1):
print s,
sys.stdout.flush() # explicitly flush the buffer

instead.

Peter


Nov 22 '05 #3

P: n/a
On 18 Nov 2005 05:08:39 -0800, "pe*****@gmail.com" <pe*****@gmail.com> wrote:
This works exactly as you would expect::

from time import sleep
def foo(on='ABC'):
for e in list(on):
sleep(1)
yield e

When I run this on the command line It takes about 3 seconds to
complete and the first letter is shown after 1 second.
But, how do I wrap the function somewhere else::

from time import sleep
def foo(on):
for e in list(on):
sleep(1)
yield e

def wrapper(x):
if x < 0:
return foo('ABC')
else:
return foo('XYZ')

When I run this, variable three letters are shown and it takes 3
seconds for the whole thing to complete. The problem is that the whole
iteration is glogged up in the wrapper() function because the first
letter is shown after 3 seconds and then all letters are shown at the
same time.

How do I wrap functions that return iterators? ...if possible.

Make the wrapper itself an iterable? E.g., is this the effect you wanted?
from time import sleep
def foo(on): ... for e in on:
... sleep(1)
... yield e
... def wrapper(x): ... if x < 0:
... for e in foo('ABC'): yield e
... else:
... for e in foo('XYZ'): yield e
... wrapper(-1) <generator object at 0x02EF3D8C> import sys
for c in wrapper(-1): sys.stdout.write(c); sys.stdout.flush() ...
ABC>>> for c in wrapper(+1): sys.stdout.write(c); sys.stdout.flush()

...
XYZ>>>

Regards,
Bengt Richter
Nov 22 '05 #4

P: n/a
On 18 Nov 2005 05:08:39 -0800, "pe*****@gmail.com" <pe*****@gmail.com> wrote:
This works exactly as you would expect::

from time import sleep
def foo(on='ABC'):
for e in list(on):
sleep(1)
yield e

When I run this on the command line It takes about 3 seconds to
complete and the first letter is shown after 1 second.
But, how do I wrap the function somewhere else::

from time import sleep
def foo(on):
for e in list(on):
sleep(1)
yield e

def wrapper(x):
if x < 0:
return foo('ABC')
else:
return foo('XYZ')

When I run this, variable three letters are shown and it takes 3
seconds for the whole thing to complete. The problem is that the whole
iteration is glogged up in the wrapper() function because the first
letter is shown after 3 seconds and then all letters are shown at the
same time.

How do I wrap functions that return iterators? ...if possible.

Make the wrapper itself an iterable? E.g., is this the effect you wanted?
from time import sleep
def foo(on): ... for e in on:
... sleep(1)
... yield e
... def wrapper(x): ... if x < 0:
... for e in foo('ABC'): yield e
... else:
... for e in foo('XYZ'): yield e
... wrapper(-1) <generator object at 0x02EF3D8C> import sys
for c in wrapper(-1): sys.stdout.write(c); sys.stdout.flush() ...
ABC>>> for c in wrapper(+1): sys.stdout.write(c); sys.stdout.flush()

...
XYZ>>>

Regards,
Bengt Richter
Nov 22 '05 #5

This discussion thread is closed

Replies have been disabled for this discussion.