Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Python curious behavior
#1
Experimenting with generators and functions I tried the following example:

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 j
And 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?
Reply


Messages In This Thread
Python curious behavior - by scidam - Jul-23-2019, 05:16 AM
RE: Python curious behavior - by DeaD_EyE - Jul-23-2019, 07:09 AM
RE: Python curious behavior - by scidam - Jul-23-2019, 11:41 AM

Possibly Related Threads…
Thread Author Replies Views Last Post
Exclamation Python 3.10.1 32 Windows setup Virus behavior SapG20211215 8 3,104 Dec-15-2021, 06:51 PM
Last Post: snippsat

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020