I have a function (f) with a yield. I have a list (E).
If I try E += f() then f() doesn’t return a generator object, but instead runs the function, which throws an exception because some global variables aren’t ready.
To forestall any comments, I know E += f() is wrong, but it provides an example for my question. If I do the right thing E += [f()] or E.append(f()) then f() returns a generator object and the code of f() is not evaluated till the generator object’s next method is called.
My question is, why is f() being evaluated in the wrong situation at all, and why instead is the exception raised not something along the lines of “function object not iterable”.
Because the expression
f()callsf, andE += f()will run the generator until its end and append the values it generates toE. It’s not “wrong” at all, but it does require a fully workingfthat yields a finite number of values:By contrast,
E += [f()]will callf, but then stops before the first line of the code because then the interpreter has a complete enough object, namely the generator object, to store in the single-element list[f()]. Only later, when you request more elements fromE[-1], will code up to the firstyieldrun and the exception be raised.