PEP 288: Generator Attributes
PEP 288 has been updated and undeferred. Comments are solicited. The old proposal for generator parameter passing with g.next(val) has been replaced with simply using attributes in about the same way as classes: def outputCaps(logfile): while True: line = __self__.data logfile.write(line.upper) yield None outputCaps.data = "" # optional attribute initialization g = outputCaps(open('logfil.txt','w')) for line in open('myfile.txt'): g.data = line g.next() The separate proposed for generator exceptions is unmodified from before.
On Friday, Nov 22, 2002, at 09:46 Europe/Amsterdam, Raymond Hettinger wrote:
def outputCaps(logfile): while True: line = __self__.data logfile.write(line.upper) yield None outputCaps.data = "" # optional attribute initialization
g = outputCaps(open('logfil.txt','w')) for line in open('myfile.txt'): g.data = line g.next()
I don't like it, there's "Magic! Magic!" written all over it.
Generators have always given me that feeling (you start reading them as
a function, then 20 lines down you meet a "yield" and suddenly realize
you have to start reading at the top again, keeping in mind that this
is a persistent stack frame), but with the __self__ plus the fact that
you local variables may not be what they appear to be makes it hairy.
You basically cannot understand the code without knowing the code of
the caller. There's also absolutely no way to get encapsulation. So
count me in for a -1.
Generators have to me always felt more "class-instance-like" than
"function-like", and I guess this just goes to show it.
--
- Jack Jansen
On Friday, Nov 22, 2002, at 09:46 Europe/Amsterdam, Raymond Hettinger wrote:
def outputCaps(logfile): while True: line = __self__.data logfile.write(line.upper) yield None outputCaps.data = "" # optional attribute initialization
g = outputCaps(open('logfil.txt','w')) for line in open('myfile.txt'): g.data = line g.next()
[Jack]
I don't like it, there's "Magic! Magic!" written all over it. Generators have always given me that feeling (you start reading them as a function, then 20 lines down you meet a "yield" and suddenly realize you have to start reading at the top again, keeping in mind that this is a persistent stack frame), but with the __self__ plus the fact that you local variables may not be what they appear to be makes it hairy. You basically cannot understand the code without knowing the code of the caller. There's also absolutely no way to get encapsulation. So count me in for a -1.
Ditto here. The PEP is way too thin on rationale. It has some examples but doesn't explain why this is better than what you woul ddo in current Python. Since passing a simple objects as an extra argument to the generator is all that's needed to pass extra values into a generator between next() calls, I don't see the advantage. And __self__ is butt-ugly.
Generators have to me always felt more "class-instance-like" than "function-like", and I guess this just goes to show it.
--Guido van Rossum (home page: http://www.python.org/~guido/)
[Jack Jansen]
I don't like it, there's "Magic! Magic!" written all over it. Generators have always given me that feeling (you start reading them as a function, then 20 lines down you meet a "yield" and suddenly realize you have to start reading at the top again, keeping in mind that this is a persistent stack frame),
Except you don't need to do such a thing -- "yield" is much the same as "print" this way. Both have the same effect on the stack frame: none. So if you don't find print to be confusing wrt local state, you shouldn't find yield confusing wrt local state either.
... Generators have to me always felt more "class-instance-like" than "function-like",
I *exoect* you'll feel more the opposite the more you use them. Heck, they're so much like functions that Guido reused "def" for them <wink>.
"Raymond Hettinger"
PEP 288 has been updated and undeferred. Comments are solicited.
The old proposal for generator parameter passing with g.next(val) has been replaced with simply using attributes in about the same way as classes:
def outputCaps(logfile): while True: line = __self__.data logfile.write(line.upper) yield None outputCaps.data = "" # optional attribute initialization
g = outputCaps(open('logfil.txt','w')) for line in open('myfile.txt'): g.data = line g.next()
-1 1. Having assignment of a dummy attribute to a (generator) function unlock assignment of an attribute of the same name to the otherwise read-only generator produced by that function is way too magical. It also breaks the illusion of simplicity and ignorance of detail allowed when generators are used in for loops. 2. Magical use of implicit '__self__' will likely increase questions about the self-object as the initial parameter of methods and requests that it be removed or worse, be made optional. Terry J. Reedy
participants (5)
-
Guido van Rossum
-
Jack Jansen
-
Raymond Hettinger
-
Terry Reedy
-
Tim Peters