Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does adding parenthesis around a yield call in a generator allow it to compile/run?

I have a method:

@gen.coroutine
def my_func(x):
    return 2 * x

basically, a tornado coroutine.

I am making a list such as:

my_funcs = []
for x in range(0, 10):
    f = yield my_func(x)
    my_funcs.append(x)

In trying to make this a list comprehension such as:

my_funcs = [yield my_func(i) for i in range(0,10)]

I realized this was invalid syntax. It turns out you can do this using () around the yield:

my_funcs = [(yield my_func(i)) for i in range(0,10)]
  • Does this behavior (the syntax for wrapping a yield foo() call in () such as (yield foo() ) in order to allow this above code to execute) have a specific type of name?
  • Is it some form of operator precedence with yield?
  • Is this behavior with yield documented somewhere?

Python 2.7.11 on OSX. This code does need to work in both Python2/3 which is why the above list comprehension is not a good idea (see here for why, the above list comp works in Python 2.7 but is broken in Python 3).

like image 653
enderland Avatar asked Oct 17 '16 19:10

enderland


People also ask

Can you use yield in list comprehension?

The yield expression is only used when defining a generator function and thus can only be used in the body of a function definition. This has been confirmed to be a bug in issue 10544.

What is yield from in Python?

Yield is a keyword in Python that is used to return from a function without destroying the states of its local variable and when the function is called, the execution starts from the last yield statement. Any function that contains a yield keyword is termed a generator. Hence, yield is what makes a generator.

What does a generator return in Python?

Simply speaking, a generator is a function that returns an object (iterator) which we can iterate over (one value at a time).

How do generators work Python?

A Python generator is a function that produces a sequence of results. It works by maintaining its local state, so that the function can resume again exactly where it left off when called subsequent times. Thus, you can think of a generator as something like a powerful iterator.


1 Answers

yield expressions must be parenthesized in any context except as an entire statement or as the right-hand side of an assignment:

# If your code doesn't look like this, you need parentheses:
yield x
y = yield x

This is stated in the PEP that introduced yield expressions (as opposed to yield statements), and it's implied by the contexts in which yield_expr appears in the grammar, although no one is expecting you to read the grammar:

A yield-expression must always be parenthesized except when it occurs at the top-level expression on the right-hand side of an assignment.

like image 105
user2357112 supports Monica Avatar answered Sep 23 '22 16:09

user2357112 supports Monica