enderland
enderland

Reputation: 14185

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)]

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).

Upvotes: 5

Views: 641

Answers (1)

user2357112
user2357112

Reputation: 281683

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.

Upvotes: 5

Related Questions