On Thu, Aug 23, 2018 at 3:56 AM, Rhodri James <rho...@kynesim.co.uk> wrote: > On 22/08/18 14:38, Jonathan Fine wrote: >>>>> def fn(): >> >> ... if None: >> ... yield >> ... >>>>> >>>>> list(fn()) # Fails, unless fn is a generator function. >> >> []
Actually, it fails unless fn returns some sort of iterable. >> I think what's happening is this. Even though the None-guarded yield >> has been optimised away, it leaves a residue. Namely, that there's a >> yield in the function. Hence fn() is an iterator. >> >> Having explained the surprise, here's how it can help you. Suppose you >> have a long function body, with a single yield at the bottom. If you >> write like this: >> >> def my_very_long_function_with_one_yield_point(...): >> if None: yield # This is a generator function. >> >> then the next programmer can know immediately that it's a generator >> function. > > > Ew. > > I'd prefer this way of doing it: > > def my_very_long_function_with_one_yield_point(...): > # This is a generator > Or you could use a return type annotation. Why should generator objects be special? A generator function is very similar to a function that returns a list, except that it can yield values as it gets them, rather than batching them up to the end. A generator function is a function which returns an iterable object of the type "generator". How is it different from a function that returns an integer? They return different things. How do you show what a function returns? You annotate it, put it in the docstring, put it in external docs... It's a function. It does something, it returns something. That's it. ChrisA _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/