473,399 Members | 2,774 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,399 software developers and data experts.

Generators and their next() and send() methods

Hello,

I was playing around a bit with generators using next() and send(). And
I was wondering why an extra send() method was introduced instead of
simply allowing an argument for next().

Also, I find it a bit counter-intuitive that send(42) not only "sets"
the generator to the specified value, but yields the next value at the
same time.

As an exercise, I wanted to somehow "modify" a generator so that it
would have a next() method accepting an argument, something like

@myway
def gen():
pass

But I failed to come up with an implementation of the myway() function.

Any comments and/or suggestions?

Greetings,
Thomas

--
Ce n'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!
(Coluche)
Nov 15 '08 #1
7 2862
Thomas Mlynarczyk <th****@mlynarczyk-webdesign.dewrites:
Hello,

I was playing around a bit with generators using next() and
send(). And I was wondering why an extra send() method was introduced
instead of simply allowing an argument for next().

Also, I find it a bit counter-intuitive that send(42) not only "sets"
the generator to the specified value, but yields the next value at the
same time.
If you want to simply 'set' the generator (by which I take you mean
'change its state') without without iterating it one step, then what you
need is a class with an __iter__() method. Then you can change the
state of the object between calls to next(). E.g.
>>class MyGenerator(object):
.... def __init__(self, v): self.v = v
.... def __iter__(self):
.... for x in range(10):
.... yield self.v
....
>>g = MyGenerator(5)
for i in g:
.... g.v = input("val:")
.... print i
....
val:4
5
val:10
4
val:34
10
val:56
34
val:

Etc...

--
Arnaud
Nov 15 '08 #2
Arnaud Delobelle schrieb:
If you want to simply 'set' the generator (by which I take you mean
'change its state') without without iterating it one step, then what you
need is a class with an __iter__() method. Then you can change the
state of the object between calls to next(). E.g.
>>>class MyGenerator(object):
... def __init__(self, v): self.v = v
... def __iter__(self):
... for x in range(10):
... yield self.v
...
>>>g = MyGenerator(5)
for i in g:
... g.v = input("val:")
... print i
That's a good idea, thanks! Meanwhile I have succeeded in writing a
decorator which allows an argument for next():

def myway( g ):
class mygen( object ):
def __init__( self, n ):
self.g = g( n )
def __iter__( self ):
return self
def next( self, s = None ):
return self.g.next() if s is None else self.g.send( s )
def send( self, s ):
return self.g.send( s )
return mygen

@myway
def gen( n ):
i = 0
while i <= n:
s = yield i
if s is not None:
i = s
else:
i += 1

Of course, this is just an exercise -- it doesn't look as if it's worth
using @mayway in any "real" code just to be able to write g.next(42)
instead of g.send(42). Still, I would like to know why it was decided to
introduce a send() method instead of allowing an argument for next().

Thanks and greetings,
Thomas
--
Ce n'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!
(Coluche)
Nov 16 '08 #3
On Nov 17, 7:36*am, Thomas Mlynarczyk <tho...@mlynarczyk-webdesign.de>
wrote:
Still, I would like to know why it was decided to
introduce a send() method instead of allowing an argument for next().
Hey Thomas,

A great place to gain insight into the reasoning behind changes to
Python is the PEPs:

http://www.python.org/dev/peps/pep-0342/

That links to the original proposal to extend the generator behaviour
to include send. I haven't the time right now to read it but if
anything is going to explain the choice, it'll be there.

At a guess, I'd expect a new method was chosen to provide semantic
distinctness with the original behaviour. Or maybe so it wouldn't
break any existing code with decorators such as your's :)

Nov 17 '08 #4
On Nov 16, 3:36*pm, Thomas Mlynarczyk <tho...@mlynarczyk-webdesign.de>
wrote:
Arnaud Delobelle schrieb:
If you want to simply 'set' the generator (by which I take you mean
'change its state') without without iterating it one step, then what you
need is a class with an __iter__() method. *Then you can change the
state of the object between calls to next(). *E.g.
>>class MyGenerator(object):
... * * def __init__(self, v): self.v = v
... * * def __iter__(self):
... * * * * for x in range(10):
... * * * * * * yield self.v
...
>>g = MyGenerator(5)
for i in g:
... * * g.v = input("val:")
... * * print i

That's a good idea, thanks! Meanwhile I have succeeded in writing a
decorator which allows an argument for next():
Here's a different structure if you want it. Untested.

def myway( g ):
def init( *ar, **kw ):
g= g( *ar, **kw )
* * *class mygen( object ):
* * * * *def __iter__( self ):
* * * * * * *return self
* * * * *def next( self, s= None ):
* * * * * * *return g.next() if s is None else g.send( s )
* * * * *def send( self, s ):
* * * * * * *return g.send( s )
* * *return mygen
return init

And, if you don't intend to use 'myway' on 'listiterator's and such,
'send( None )' is equivalent to 'next( )'.

def myway( g ):
def init( *ar, **kw ):
g= g( *ar, **kw )
class mygen( object ):
def __iter__( self ):
return self
def next( self, s= None ):
return g.send( s )
def send( self, s ):
return g.send( s )
return mygen
return init

There's probably a typo in it.
Nov 17 '08 #5
alex23 schrieb:
http://www.python.org/dev/peps/pep-0342/
That links to the original proposal to extend the generator behaviour
After some searching, I found this as a remark in parentheses:

"Introducing a new method instead of overloading next() minimizes
overhead for simple next() calls."

And also a (little) more detailed explanation. So, basically, allowing
an argument for next() would have meant more overhead in the Python
implementation. Still, I don't quite see why, as this could be detected
at compile time, couldn't it?

On the other hand, if I understood correctly, I can use send(None) as an
equivalent of next(). So, while I cannot have next(argument) instead of
send(argument), I can have send(None) instead of next().
At a guess, I'd expect a new method was chosen to provide semantic
distinctness with the original behaviour.
But the semantics would not have changed, they would only be "extended"
and thus remain "compatible", wouldn't they?

Greetings,
Thomas

--
Ce n'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!
(Coluche)
Nov 18 '08 #6
Aaron Brady schrieb:
And, if you don't intend to use 'myway' on 'listiterator's and such,
'send( None )' is equivalent to 'next( )'.
I didn't know that. But doesn't that impose a restriction somehow? It
makes it impossible to send a None to a generator.

Greetings,
Thomas

--
Ce n'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!
(Coluche)
Nov 18 '08 #7
On Nov 18, 5:20*pm, Thomas Mlynarczyk <tho...@mlynarczyk-webdesign.de>
wrote:
Aaron Brady schrieb:
And, if you don't intend to use 'myway' on 'listiterator's and such,
'send( None )' is equivalent to 'next( )'.

I didn't know that. But doesn't that impose a restriction somehow? It
makes it impossible to send a None to a generator.
No, None is a valid value to use with send. Not all iterators support
send.
Nov 19 '08 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

23
by: Francis Avila | last post by:
Below is an implementation a 'flattening' recursive generator (take a nested iterator and remove all its nesting). Is this possibly general and useful enough to be included in itertools? (I know...
9
by: Francis Avila | last post by:
A little annoyed one day that I couldn't use the statefulness of generators as "resumable functions", I came across Hettinger's PEP 288 (http://www.python.org/peps/pep-0288.html, still listed as...
4
by: The_Incubator | last post by:
As the subject suggests, I am interested in using Python as a scripting language for a game that is primarily implemented in C++, and I am also interested in using generators in those scripts... ...
1
by: fishboy | last post by:
Howdy, I'm in middle of a personal project. Eventually it will download multipart binary attachments and look for missing parts on other servers. And so far I've got it to walk a newsgroup and...
0
by: fishboy | last post by:
Howdy, Sorry if this is a double post. First try seemed to go into hyperspace. I'm working on a personal project. It's going to be a multipart binary attachment downloader that will search...
15
by: Jordan Rastrick | last post by:
First, a disclaimer. I am a second year Maths and Computer Science undergraduate, and this is my first time ever on Usenet (I guess I'm part of the http generation). On top of that, I have been...
3
by: Michael Sparks | last post by:
Hi, I'm posting a link to this since I hope it's of interest to people here :) I've written up the talk I gave at ACCU Python UK on the Kamaelia Framework, and it's been published as a BBC...
5
by: Andrew Koenig | last post by:
Can anyone think of an easy technique for creating an object that acts like a generator but has additional methods? For example, it might be nice to be able to iterate through an associative...
7
by: Ben Sizer | last post by:
A simple question - can anybody give a short example of how these work and what they are good for? I've read PEP 342 and the associated bit in the What's New section and it's still all Greek to me....
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.