Experimenting with generators and functions I tried the following example:
This behavior remains true not only if we are using
We can find an explanation of this behavior in PEP255,
Nevertheless, when
Even being explainable from PEPs, this issue produces very unintuitive behavior, and probably a special warning needs to be raised (e.g. SyntaxWarning or something else) when one tries to execute such construction.
What do you think about this behavior? Do Python needs to raise a special warning to users, when they try to use both
def myfunc(k): if k == 3: return ["A string..."] else: yield from range(k)What is expected behavior of this function, if we call it, e.g., as follows
list(myfunc(3))
?list(myfunc(3))
Output:[]
Why does this function return an empty list? This is quite unintuitive behavior of Python, because list(["A string..."])
should return ["A string..."]
. This behavior remains true not only if we are using
yield from
construction, e.g.def myfunc1(k): if k == 3: return ["A string..."] else: for j in range(k): yield jAnd we still got unintuitive result:
list(myfunc1(3))
Output:[]
In Python 2.x, a try to define such function (myfunc1
) yields SyntaxError.We can find an explanation of this behavior in PEP255,
Quote: A generator function can also contain return statements of the form:
return
Note that an expression_list is not allowed on return statements in the body of a generator (although, of course, they may appear in the bodies of non-generator functions nested within the generator).
When a return statement is encountered, control proceeds as in any function return, executing the appropriate finally clauses (if any exist). Then a StopIteration exception is raised, signalling that the iterator is exhausted. A StopIteration exception is also raised if control flows off the end of the generator without an explicit return.
Nevertheless, when
yield from
has come (Python 3.3+, see PEP380), it becomes possible to use return (with values) inside generators. The essence of such behavior becomes clear from PEP380:Quote:2. In a generator, the statement
return value
is semantically equivalent to
raise StopIteration(value)
except that, as currently, the exception cannot be caught by except clauses within the returning generator.
Even being explainable from PEPs, this issue produces very unintuitive behavior, and probably a special warning needs to be raised (e.g. SyntaxWarning or something else) when one tries to execute such construction.
What do you think about this behavior? Do Python needs to raise a special warning to users, when they try to use both
return
and yield/yield from
in the same function/generator's body?