Tip 58 Yield, Do Not Return

Pythonic Programming — by Dmitry Zinoviev (69 / 116)

The Pragmatic Programmers
The Pragmatic Programmers

--

👈 Chain Function Calls | TOC | Return and Apply Functions 👉

★★★2.7, 3.4+ Once you return from a Python function, you can never come back again and continue from the next line after the return statement. This behavior is well understood and rarely causes lamentations — except when you want to implement a generator.

A generator is an object that, when asked, “lazily” produces one item at a time. From a caller’s perspective, it looks like a function with internal memory that remembers where it stopped after returning the previous result and resumes from the next line — something that I claimed earlier not to be possible. Some standard generator functions are shown in Tip 17, Avoid range() in Loops, but you can quickly write generators yourself. All you need is to replace return with yield. A function with a yield returns a generator object. You can use the object as a parameter to another function or explicitly elicit the generated values by applying the built-in functions next (one item) or list (all items):

​ ​def​ ​fortune_teller​(attempts=2):
​ ​for​ _ ​in​ range(attempts):
​ ​yield​ bool(random.randint(0, 1))
​ ​return​ ​'Do not call me again!'​
​ oracle = fortune_teller(2) ​# The generator created​
​ next(oracle)
​=> ​False​​ next(oracle)​=> ​True​

--

--

The Pragmatic Programmers
The Pragmatic Programmers

We create timely, practical books and learning resources on classic and cutting-edge topics to help you practice your craft and accelerate your career.