See also section 16.1.7.
#!/usr/bin/env python3 # taken from https://lerner.co.il/2020/05/08/making-sense-of-generators-coroutines-and-yield-from-in-python/ import random # generator function, returns a generator def myfunc1(): yield 1 yield 2 yield 3 # coroutine, yield is on the right side of an assignment def myfunc2(): x = ” while True: print(f'Yielding x ({x}) and waiting') x = yield x # the value is received from send() if x is None: break print(f'Got x {x}. Doubling.') x = x * 2 def pl_sentence(sentence): output = [] for one_word in sentence.split(): if one_word[0] in 'aeiou': output.append(one_word + 'way') else: output.append(one_word[1:] + one_word[0] + 'ay') return ' '.join(output) def pig_latin_translator(): s = ” while True: s = yield pl_sentence(s) if s is None: break def bad_service_chatbot(): answers = ["We don't do that", "We will get back to you right away", "Your call is very important to us", "Sorry, my manager is unavailable"] yield "Can I help you?" s = ” while True: if s is None: break s = yield random.choice(answers) def wrapper(data): for one_item in data: yield one_item def wrapper2(data): yield from data def switchboard(): choice = yield "Send 1 for Pig Latin, 2 for support" if choice == 1: yield from pig_latin_translator() elif choice == 2: yield from bad_service_chatbot() else: return def switchboard2(): while True: choice = yield "1 for PL, 2 for support, 3 to exit" if choice == 1: yield from pig_latin_translator() elif choice == 2: yield from bad_service_chatbot() elif choice == 3: return else: print('Bad choice; try again') def main(): g = myfunc1() # g is a generator object implementing the iterator protocaol # it knows what to do in a foor loop for i in g: print( "%d" % i) g = myfunc1() print( "%d" % next(g)) print( "%d" % next(g)) print( "%d" % next(g)) g = myfunc2() # coroutine print( "main: %s" % repr( next(g))) # -> ” print( "main: %s" % repr( g.send(10))) # -> 20 print( "main: %s" % repr( g.send(123))) # -> 246 g = pig_latin_translator() print( "main: %s" % repr( next(g))) print( "main: %s" % repr( g.send( "this is a test"))) print( "main: %s" % repr( g.send( "hello"))) g2 = bad_service_chatbot() print( "%s" % repr( next( g2))) print( "%s" % repr( g2.send( "I want to complain"))) g = wrapper( 'abcd') print( "%s" % repr( list( g))) g = wrapper2( 'abcd') print( "%s" % repr( list( g))) s = switchboard() print( "%s" % repr( next( s))) print( "%s" % repr( s.send(1))) print( "%s" % repr( s.send('hello'))) s = switchboard2() print( "%s" % repr( next( s))) print( "%s" % repr( s.send(2))) print( "%s" % repr( s.send('hi there'))) print( "%s" % repr( s.send( None))) print( "%s" % repr( s.send(1))) print( "%s" % repr( s.send( "hello"))) return if __name__ == "__main__": main()