4 ms·
The presence of the yield keyword in a function definition means the function will return a generator when it's called. Therefore "print "aaa"" is not executed
by gejjaxxita 14y ago
The presence of the yield keyword in a function definition means the function will return a generator when it's called. Therefore "print "aaa"" is not executed on "mygen = createGenerator()" as expected. "print "aaa"" is infact executed when mygen.next() is called.
To emphasise this point, it is the existence of the yield keyword which causes the function to return a generator when it is called - it will not execute any of the code. This is why the following results in an error:
>>> def hello(j):
... if j>2:
... return "big number"
... elif j<2:
... yield "small number"
A return keyword cannot exist within the body of a generator - it makes no sense.
A more detailed explanation can be found here http://docs.python.org/2.5/ref/yieldexpr.html http://docs.python.org/2.5/ref/yieldexpr.html
- jiggy2011 14y agoI think I mostly understand the idea, the presence of the yield statement transforms the nature of the parent function itself and makes evaluation lazy. This seems a little weird syntactically though because it feels like the interpreter is somehow reading ahead in the program. It also means you don't necessarily know that this is a lazy function unless you read to the end. A more intuitive syntax might be something like: def lazy createGenerator(): print "aaa" yield "bbb"
- csense 14y agoThis syntax would against the Python principle DRY (Don't Repeat Yourself): The "lazy" keyword conveys no information that doesn't exist in the function body. Also, Python has precedent for this scanning behavior. One of the fundamental features of Python is that the scope of a variable is determined by the presence of an assignment statement in a function. For example: a = 1 def f(): print a # UnboundLocalError occurs here a = 2 f() If you know Javascript, think about how often you need to use the "var" keyword in that language, and how easy it is to accidentally pollute the global namespace by omitting it.
- gejjaxxita 14y agoThis is an insightful point. I tend to regard this scanning behaviour as a "quirk" rather than something fitting in more with some deeper Python philosophy. A specific syntax for generators would in my view be generally superior, containing the same number of new keywords (generator now replacing yield) and providing enhanced clarity. generator hello(n): for i in range(n): return i I am generally neutral about variable scope being determined by the assignment of a statement in a function - in 99.99% of cases the intuitive thing happens.
- eurleif 14y agoExcept you can use `return` without argument to return early from a generator, and `yield` without argument yields None, so they need to be separate keywords.
- gejjaxxita 14y agoThis functionality is so arcane that it's not needed.
- eurleif 14y agoEarly return is definitely needed. I guess you could make bare `return` early return, and `return None` the way to yield None, but that's kind of confusing.
- gejjaxxita 14y agoI agree that would be confusing, but I question that early return is needed - I don't think I've ever seen a generator example where early return is used. It could be that it's because I haven't seen enough examples of course. Please share some examples of a generator with early return which can't be accomplished easily and clearly in some other way.
- 14y ago