forked from bslatkin/effectivepython
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathatom.xml
More file actions
978 lines (751 loc) · 149 KB
/
atom.xml
File metadata and controls
978 lines (751 loc) · 149 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Effective Python</title><link href="http://www.effectivepython.com/" rel="alternate"></link><link href="http://www.effectivepython.com/atom.xml" rel="self"></link><id>http://www.effectivepython.com/</id><updated>2016-08-06T18:45:00-07:00</updated><entry><title>Python Eficaz</title><link href="http://www.effectivepython.com/2016/08/06/python-eficaz-portugu%C3%AAs/" rel="alternate"></link><updated>2016-08-06T18:45:00-07:00</updated><author><name>Brett Slatkin</name></author><id>tag:www.effectivepython.com,2016-08-06:2016/08/06/python-eficaz-português/</id><summary type="html"><p><a href="http://novatec.com.br/livros/python-eficaz/"><img class="learn-more-photo" alt="Python Eficaz" src="http://www.effectivepython.com/images/cover_pt_br.jpg"></a></p>
<p>The publishing house Novatec Editora has translated and released a Portuguese version of <em>Effective Python</em>. You can buy the book <a href="http://novatec.com.br/livros/python-eficaz/">directly from the publisher</a>.</p></summary></entry><entry><title>Effective Python 简体中文</title><link href="http://www.effectivepython.com/2016/05/07/effective-python-hans/" rel="alternate"></link><updated>2016-05-07T09:00:00-07:00</updated><author><name>Brett Slatkin</name></author><id>tag:www.effectivepython.com,2016-05-07:2016/05/07/effective-python-hans/</id><summary type="html"><p><a href="https://www.amazon.cn/Effective-Python-%E7%BC%96%E5%86%99%E9%AB%98%E8%B4%A8%E9%87%8FPython%E4%BB%A3%E7%A0%81%E7%9A%8459%E4%B8%AA%E6%9C%89%E6%95%88%E6%96%B9%E6%B3%95-%E5%B8%83%E9%9B%B7%E7%89%B9%C2%B7%E6%96%AF%E6%8B%89%E7%89%B9%E9%87%91/dp/B01ASI36QS"><img class="learn-more-photo" alt="Effective Python 简体中文" src="http://www.effectivepython.com/images/cover_zh_hans.jpg"></a></p>
<p>The publishing house 机械工业出版社 (China Machine Press) has translated and released a Chinese (Simplified) version of <em>Effective Python</em>. You can buy the book <a href="http://www.cmpbook.com/stackroom.php?id=41800">directly from the publisher</a> or <a href="https://www.amazon.cn/Effective-Python-%E7%BC%96%E5%86%99%E9%AB%98%E8%B4%A8%E9%87%8FPython%E4%BB%A3%E7%A0%81%E7%9A%8459%E4%B8%AA%E6%9C%89%E6%95%88%E6%96%B9%E6%B3%95-%E5%B8%83%E9%9B%B7%E7%89%B9%C2%B7%E6%96%AF%E6%8B%89%E7%89%B9%E9%87%91/dp/B01ASI36QS">get it on Amazon.cn</a>.</p></summary></entry><entry><title>Effective Python 파이썬 코딩의 기술</title><link href="http://www.effectivepython.com/2016/04/03/effective-python-kr/" rel="alternate"></link><updated>2016-04-03T17:00:00-07:00</updated><author><name>Brett Slatkin</name></author><id>tag:www.effectivepython.com,2016-04-03:2016/04/03/effective-python-kr/</id><summary type="html"><p><a href="http://www.gilbut.co.kr/book/bookView.aspx?bookcode=BN001430"><img class="learn-more-photo" alt="Effective Python 파이썬 코딩의 기술" src="http://www.effectivepython.com/images/cover_kr.jpg"></a></p>
<p>The publishing house Gilbut Inc. has translated and released a Korean version of <em>Effective Python</em>. <a href="http://www.gilbut.co.kr/book/bookView.aspx?bookcode=BN001430">The publisher&#8217;s website</a> links to many different retailers online where you can buy the&nbsp;book.</p></summary></entry><entry><title>Effective Python 日本語</title><link href="http://www.effectivepython.com/2016/01/23/effective-python-jp/" rel="alternate"></link><updated>2016-01-23T09:00:00-08:00</updated><author><name>Brett Slatkin</name></author><id>tag:www.effectivepython.com,2016-01-23:2016/01/23/effective-python-jp/</id><summary type="html"><p><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873117569"><img class="learn-more-photo" alt="Effective Python 日本語" src="http://www.effectivepython.com/images/cover_jp.jpg"></a></p>
<p>The publishing house O&#8217;Reilly Japan has translated and released a Japanese version of <em>Effective Python</em>. You can buy the book <a href="http://www.oreilly.co.jp/books/9784873117560/">directly from the publisher</a> or <a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873117569">get it on Amazon.jp</a>.</p></summary></entry><entry><title>Efektywny Python</title><link href="http://www.effectivepython.com/2015/11/20/efektywny-python-pl/" rel="alternate"></link><updated>2015-11-15T09:00:00-08:00</updated><author><name>Brett Slatkin</name></author><id>tag:www.effectivepython.com,2015-11-20:2015/11/20/efektywny-python-pl/</id><summary type="html"><p><a href="http://helion.pl/ksiazki/efektywny-python-59-sposobow-na-lepszy-kod-brett-slatkin,efepyt.htm"><img class="learn-more-photo" alt="Efektywny Python" src="http://www.effectivepython.com/images/cover_pl.jpg"></a></p>
<p>The publishing house Helion has translated and released a Polish version of <em>Effective Python</em>. You can buy the book <a href="http://helion.pl/ksiazki/efektywny-python-59-sposobow-na-lepszy-kod-brett-slatkin,efepyt.htm">directly from the publisher</a>.</p></summary></entry><entry><title>Effektiv Python programmieren</title><link href="http://www.effectivepython.com/2015/11/15/effektiv-python-deutsch/" rel="alternate"></link><updated>2015-11-15T21:40:00-08:00</updated><author><name>Brett Slatkin</name></author><id>tag:www.effectivepython.com,2015-11-15:2015/11/15/effektiv-python-deutsch/</id><summary type="html"><p><a href="http://www.amazon.de/Effektiv-Python-programmieren-mitp-Professional/dp/3958451810"><img class="learn-more-photo" alt="Effektiv Python programmieren" src="http://www.effectivepython.com/images/cover_de.jpg"></a></p>
<p>The publishing house mitp-Verlag has translated and released a German version of <em>Effective Python</em>. You can buy the book <a href="http://www.mitp.de/IT-Web/Programmierung/Effektiv-Python-programmieren.html">directly from the publisher</a> or <a href="http://www.amazon.de/Effektiv-Python-programmieren-mitp-Professional/dp/3958451810">get it on Amazon.de</a> (including Kindle&nbsp;edition).</p></summary></entry><entry><title>Talk Python To Me Podcast</title><link href="http://www.effectivepython.com/2015/09/09/talk-python-to-me-podcast/" rel="alternate"></link><updated>2015-09-09T09:00:00-07:00</updated><author><name>Brett Slatkin</name></author><id>tag:www.effectivepython.com,2015-09-09:2015/09/09/talk-python-to-me-podcast/</id><summary type="html"><p>I was invited on to the <a href="https://talkpython.fm/episodes/show/25/effective-python">Talk Python To Me Podcast</a> to talk about <em>Effective Python</em>. You can <a href="https://talkpython.fm/episodes/transcript/25/effective-python">read the full transcript here</a> or listen to the audio embedded below. Thanks to Michael Kennedy for being such a welcoming&nbsp;host.</p>
<p><audio controls>
<source src="https://talkpython.fm/episodes/download/25/effective-python.mp3" type="audio/mpeg">
</audio></p></summary></entry><entry><title>Effective Python 中文版</title><link href="http://www.effectivepython.com/2015/08/27/effective-python-cn/" rel="alternate"></link><updated>2015-08-27T09:00:00-07:00</updated><author><name>Brett Slatkin</name></author><id>tag:www.effectivepython.com,2015-08-27:2015/08/27/effective-python-cn/</id><summary type="html"><p><a href="http://books.gotop.com.tw/v_ACL043700"><img class="learn-more-photo" alt="Effective Python 中文版" src="http://www.effectivepython.com/images/cover_zh_hant.jpg"></a></p>
<p>The publishing house 碁峰 (Acer Peak) has translated and released a Chinese (Traditional) version of <em>Effective Python</em>. You can buy the book <a href="http://books.gotop.com.tw/v_ACL043700">directly from the publisher</a> or <a href="https://play.google.com/store/books/details/Brett_Slatkin_Effective_Python_%E4%B8%AD%E6%96%87%E7%89%88_%E5%AF%AB%E5%87%BA%E8%89%AF%E5%A5%BD_Python_%E7%A8%8B%E5%BC%8F%E7%9A%84?id=V2m7CgAAQBAJ">get a digital edition on Google Play</a>.</p></summary></entry><entry><title>Live Lessons Video</title><link href="http://www.effectivepython.com/2015/08/04/live-lessons-video/" rel="alternate"></link><updated>2015-08-04T09:00:00-07:00</updated><author><name>Brett Slatkin</name></author><id>tag:www.effectivepython.com,2015-08-04:2015/08/04/live-lessons-video/</id><summary type="html"><p><a href="http://www.informit.com/store/effective-python-livelessons-video-training-downloadable-9780134175164"><img alt="Effective Python Live Lessons" class="learn-more-photo" src="http://www.effectivepython.com/images/live_lessons.png"></a></p>
<p>I worked with Addison-Wesley to produce a video version of the book <em>Effective Python</em>. You can view samples and buy the video <a href="http://www.informit.com/store/effective-python-livelessons-video-training-downloadable-9780134175164">on the publisher&#8217;s website</a>. </p>
<p>It includes 5 hours of video, covering 32 items from the book in six lessons. The content is primarily me using a source code editor to write Python programs that demonstrate the items from the&nbsp;book.</p></summary></entry><entry><title>Talk at PyCon Montréal</title><link href="http://www.effectivepython.com/2015/04/10/pycon-montreal/" rel="alternate"></link><updated>2015-04-11T10:15:00-07:00</updated><author><name>Brett Slatkin</name></author><id>tag:www.effectivepython.com,2015-04-10:2015/04/10/pycon-montreal/</id><summary type="html">
<p>I gave a talk at PyCon Montréal entitled &#8220;How to Be More Effective with Functions&#8221;.</p>
<ul>
<li>The slides are embedded below (click the gear to download as a <span class="caps">PDF</span>).</li>
<li><a href="https://github.com/bslatkin/pycon2015">The code from the examples is here on GitHub</a>.</li>
<li>The <a href="https://www.youtube.com/watch?v=WjJUPxKB164">video is available here</a> (also embedded&nbsp;below).</li>
</ul>
<p><br></p>
<iframe src="https://docs.google.com/presentation/d/14GbOzGgZacdw7zQN6yt-V0MVO6upL5Gd9VJ9Il6DsHQ/embed?start=false&loop=false&delayms=10000" frameborder="0" width="480" height="389" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"></iframe>
<p><br></p>
<iframe width="640" height="360" src="https://www.youtube.com/embed/WjJUPxKB164?rel=0" frameborder="0" allowfullscreen></iframe></summary></entry><entry><title>Item 40: Consider Coroutines to Run Many Functions Concurrently</title><link href="http://www.effectivepython.com/2015/03/10/consider-coroutines-to-run-many-functions-concurrently/" rel="alternate"></link><updated>2015-03-10T22:45:00-07:00</updated><author><name>Brett Slatkin</name></author><id>tag:www.effectivepython.com,2015-03-10:2015/03/10/consider-coroutines-to-run-many-functions-concurrently/</id><summary type="html"><p><em>The following is a sample from the new book <a href="/">Effective Python</a>.</em> <br><br></p>
<p>Threads give Python programmers a way to run multiple functions seemingly at the same time. But there are three big problems with threads:</p>
<ul>
<li>
<p>They require special tools to coordinate with each other safely. This makes code that uses threads harder to reason about than procedural, single-threaded code. This complexity makes threaded code more difficult to extend and maintain over&nbsp;time.</p>
</li>
<li>
<p>Threads require a lot of memory, about <span class="caps">8MB</span> per executing thread. On many computers, that amount of memory doesn&#8217;t matter for a dozen threads or so. But what if you want your program to run tens of thousands of functions &#8220;simultaneously&#8221;? These functions may correspond to user requests to a server, pixels on a screen, particles in a simulation, etc. Running a thread per unique activity just won&#8217;t&nbsp;work.</p>
</li>
<li>
<p>Threads are costly to start. If you want to constantly be creating new concurrent functions and finishing them, the overhead of using threads becomes large and slows everything&nbsp;down.</p>
</li>
</ul>
<p>Python can work around all these issues with <em>coroutines</em>. Coroutines let you have many seemingly simultaneous functions in your Python programs. They&#8217;re implemented as an extension to generators. The cost of starting a generator coroutine is a function call. Once active, they each use less than <span class="caps">1KB</span> of memory until they&#8217;re&nbsp;exhausted.</p>
<p>Coroutines work by enabling the code consuming a generator to <code>send</code> a value back into the generator function after each <code>yield</code> expression. The generator function receives the value passed to the <code>send</code> function as the result of the corresponding <code>yield</code> expression.</p>
<div class="highlight"><pre><span class="k">def</span> <span class="nf">my_coroutine</span><span class="p">():</span>
<span class="k">while</span> <span class="bp">True</span><span class="p">:</span>
<span class="n">received</span> <span class="o">=</span> <span class="k">yield</span>
<span class="k">print</span><span class="p">(</span><span class="s">&#39;Received:&#39;</span><span class="p">,</span> <span class="n">received</span><span class="p">)</span>
<span class="n">it</span> <span class="o">=</span> <span class="n">my_coroutine</span><span class="p">()</span>
<span class="nb">next</span><span class="p">(</span><span class="n">it</span><span class="p">)</span> <span class="c"># Prime the coroutine</span>
<span class="n">it</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="s">&#39;First&#39;</span><span class="p">)</span>
<span class="n">it</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="s">&#39;Second&#39;</span><span class="p">)</span>
</pre></div>
<div class="highlight"><pre>&gt;&gt;&gt;
Received: First
Received: Second
</pre></div>
<p>The initial call to <code>next</code> is required to prepare the generator for receiving the first <code>send</code> by advancing it to the first <code>yield</code> expression. Together, <code>yield</code> and <code>send</code> provide generators with a standard way to vary their next yielded value in response to external&nbsp;input.</p>
<p>For example, say you want to implement a generator coroutine that yields the minimum value it&#8217;s been sent so far. Here the bare <code>yield</code> prepares the coroutine with the initial minimum value sent in from the outside. Then the generator repeatedly yields the new minimum in exchange for the next value to&nbsp;consider.</p>
<div class="highlight"><pre><span class="k">def</span> <span class="nf">minimize</span><span class="p">():</span>
<span class="n">current</span> <span class="o">=</span> <span class="k">yield</span>
<span class="k">while</span> <span class="bp">True</span><span class="p">:</span>
<span class="n">value</span> <span class="o">=</span> <span class="k">yield</span> <span class="n">current</span>
<span class="n">current</span> <span class="o">=</span> <span class="nb">min</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">current</span><span class="p">)</span>
</pre></div>
<p>The code consuming the generator can run one step at a time and will output the minimum value seen after each&nbsp;input.</p>
<div class="highlight"><pre><span class="n">it</span> <span class="o">=</span> <span class="n">minimize</span><span class="p">()</span>
<span class="nb">next</span><span class="p">(</span><span class="n">it</span><span class="p">)</span> <span class="c"># Prime the generator</span>
<span class="k">print</span><span class="p">(</span><span class="n">it</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="mi">10</span><span class="p">))</span>
<span class="k">print</span><span class="p">(</span><span class="n">it</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="mi">4</span><span class="p">))</span>
<span class="k">print</span><span class="p">(</span><span class="n">it</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="mi">22</span><span class="p">))</span>
<span class="k">print</span><span class="p">(</span><span class="n">it</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">))</span>
</pre></div>
<div class="highlight"><pre>&gt;&gt;&gt;
10
4
4
-1
</pre></div>
<p>The generator function will seemingly run forever, making forward progress with each new call to <code>send</code>. Like threads, coroutines are independent functions that can consume inputs from their environment and produce resulting outputs. The difference is that coroutines pause at each <code>yield</code> expression in the generator function and resume after each call to <code>send</code> from the outside. This is the magical mechanism of&nbsp;coroutines.</p>
<p>This behavior allows the code consuming the generator to take action after each <code>yield</code> expression in the coroutine. The consuming code can use the generator&#8217;s output values to call other functions and update data structures. Most importantly, it can advance other generator functions until their next <code>yield</code> expressions. By advancing many separate generators in lockstep, they will all seem to be running simultaneously, mimicking the concurrent behavior of Python&nbsp;threads.</p>
<h3>The Game of&nbsp;Life</h3>
<p>Let me demonstrate the simultaneous behavior of coroutines with an example. Say you want to use coroutines to implement <a href="http://en.wikipedia.org/wiki/Conway's_Game_of_Life">Conway&#8217;s Game of Life</a>. The rules of the game are simple. You have a two-dimensional grid of an arbitrary size. Each cell in the grid can either be alive or&nbsp;empty.</p>
<div class="highlight"><pre><span class="n">ALIVE</span> <span class="o">=</span> <span class="s">&#39;*&#39;</span>
<span class="n">EMPTY</span> <span class="o">=</span> <span class="s">&#39;-&#39;</span>
</pre></div>
<p>The game progresses one tick of the clock at a time. At each tick, each cell counts how many of its neighboring eight cells are still alive. Based on its neighbor count, each cell decides if it will keep living, die, or regenerate. Here&#8217;s an example of a 5x5 Game of Life grid after four generations with time going to the right. I&#8217;ll explain the specific rules further&nbsp;below.</p>
<div class="highlight"><pre> 0 | 1 | 2 | 3 | 4
----- | ----- | ----- | ----- | -----
-*--- | --*-- | --**- | --*-- | -----
--**- | --**- | -*--- | -*--- | -**--
---*- | --**- | --**- | --*-- | -----
----- | ----- | ----- | ----- | -----
</pre></div>
<p>I can model this game by representing each cell as a generator coroutine running in lockstep with all the&nbsp;others.</p>
<p>To implement this, first I need a way to retrieve the status of neighboring cells. I can do this with a coroutine named <code>count_neighbors</code> that works by yielding <code>Query</code> objects. The <code>Query</code> class I define myself. Its purpose is to provide the generator coroutine with a way to ask its surrounding environment for&nbsp;information.</p>
<div class="highlight"><pre><span class="n">Query</span> <span class="o">=</span> <span class="n">namedtuple</span><span class="p">(</span><span class="s">&#39;Query&#39;</span><span class="p">,</span> <span class="p">(</span><span class="s">&#39;y&#39;</span><span class="p">,</span> <span class="s">&#39;x&#39;</span><span class="p">))</span>
</pre></div>
<p>The coroutine yields a <code>Query</code> for each neighbor. The result of each <code>yield</code> expression will be the value <code>ALIVE</code> or <code>EMPTY</code>. That&#8217;s the interface contract I&#8217;ve defined between the coroutine and its consuming code. The <code>count_neighbors</code> generator sees the neighbors&#8217; states and returns the count of living&nbsp;neighbors.</p>
<div class="highlight"><pre><span class="k">def</span> <span class="nf">count_neighbors</span><span class="p">(</span><span class="n">y</span><span class="p">,</span> <span class="n">x</span><span class="p">):</span>
<span class="n">n_</span> <span class="o">=</span> <span class="k">yield</span> <span class="n">Query</span><span class="p">(</span><span class="n">y</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="n">x</span> <span class="o">+</span> <span class="mi">0</span><span class="p">)</span> <span class="c"># North</span>
<span class="n">ne</span> <span class="o">=</span> <span class="k">yield</span> <span class="n">Query</span><span class="p">(</span><span class="n">y</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="n">x</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="c"># Northeast</span>
<span class="c"># Define e_, se, s_, sw, w_, nw ...</span>
<span class="c"># ...</span>
<span class="n">neighbor_states</span> <span class="o">=</span> <span class="p">[</span><span class="n">n_</span><span class="p">,</span> <span class="n">ne</span><span class="p">,</span> <span class="n">e_</span><span class="p">,</span> <span class="n">se</span><span class="p">,</span> <span class="n">s_</span><span class="p">,</span> <span class="n">sw</span><span class="p">,</span> <span class="n">w_</span><span class="p">,</span> <span class="n">nw</span><span class="p">]</span>
<span class="n">count</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">for</span> <span class="n">state</span> <span class="ow">in</span> <span class="n">neighbor_states</span><span class="p">:</span>
<span class="k">if</span> <span class="n">state</span> <span class="o">==</span> <span class="n">ALIVE</span><span class="p">:</span>
<span class="n">count</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="k">return</span> <span class="n">count</span>
</pre></div>
<p>I can drive the <code>count_neighbors</code> coroutine with fake data to test it. Here I show how <code>Query</code> objects will be yielded for each neighbor. <code>count_neighbors</code> expects to receive cell states corresponding to each <code>Query</code> through the coroutine&#8217;s <code>send</code> method. The final count is returned in the <code>StopIteration</code> exception that is raised when the generator is exhausted by the <code>return</code> statement.</p>
<div class="highlight"><pre><span class="n">it</span> <span class="o">=</span> <span class="n">count_neighbors</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span> <span class="mi">5</span><span class="p">)</span>
<span class="n">q1</span> <span class="o">=</span> <span class="nb">next</span><span class="p">(</span><span class="n">it</span><span class="p">)</span> <span class="c"># Get the first query</span>
<span class="k">print</span><span class="p">(</span><span class="s">&#39;First yield: &#39;</span><span class="p">,</span> <span class="n">q1</span><span class="p">)</span>
<span class="n">q2</span> <span class="o">=</span> <span class="n">it</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="n">ALIVE</span><span class="p">)</span> <span class="c"># Send q1 state, get q2</span>
<span class="k">print</span><span class="p">(</span><span class="s">&#39;Second yield:&#39;</span><span class="p">,</span> <span class="n">q2</span><span class="p">)</span>
<span class="n">q3</span> <span class="o">=</span> <span class="n">it</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="n">ALIVE</span><span class="p">)</span> <span class="c"># Send q2 state, get q3</span>
<span class="c"># ...</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">count</span> <span class="o">=</span> <span class="n">it</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="n">EMPTY</span><span class="p">)</span> <span class="c"># Send q8 state, retrieve count</span>
<span class="k">except</span> <span class="ne">StopIteration</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="k">print</span><span class="p">(</span><span class="s">&#39;Count: &#39;</span><span class="p">,</span> <span class="n">e</span><span class="o">.</span><span class="n">value</span><span class="p">)</span> <span class="c"># Value from return statement</span>
</pre></div>
<div class="highlight"><pre>&gt;&gt;&gt;
First yield: Query(y=11, x=5)
Second yield: Query(y=11, x=6)
...
Count: 2
</pre></div>
<p>Now I need the ability to indicate that a cell will transition to a new state in response to the neighbor count that it found from <code>count_neighbors</code>. To do this, I define another coroutine called <code>step_cell</code>. This generator will indicate transitions in a cell&#8217;s state by yielding <code>Transition</code> objects. This is another class that I define, just like the <code>Query</code> class.</p>
<div class="highlight"><pre><span class="n">Transition</span> <span class="o">=</span> <span class="n">namedtuple</span><span class="p">(</span><span class="s">&#39;Transition&#39;</span><span class="p">,</span> <span class="p">(</span><span class="s">&#39;y&#39;</span><span class="p">,</span> <span class="s">&#39;x&#39;</span><span class="p">,</span> <span class="s">&#39;state&#39;</span><span class="p">))</span>
</pre></div>
<p>The <code>step_cell</code> coroutine receives its coordinates in the grid as arguments. It yields a <code>Query</code> to get the initial state of those coordinates. It runs <code>count_neighbors</code> to inspect the cells around it. It runs the game logic to determine what state the cell should have for the next clock tick. Finally, it yields a <code>Transition</code> object to tell the environment the cell&#8217;s next&nbsp;state.</p>
<div class="highlight"><pre><span class="k">def</span> <span class="nf">game_logic</span><span class="p">(</span><span class="n">state</span><span class="p">,</span> <span class="n">neighbors</span><span class="p">):</span>
<span class="c"># ...</span>
<span class="k">def</span> <span class="nf">step_cell</span><span class="p">(</span><span class="n">y</span><span class="p">,</span> <span class="n">x</span><span class="p">):</span>
<span class="n">state</span> <span class="o">=</span> <span class="k">yield</span> <span class="n">Query</span><span class="p">(</span><span class="n">y</span><span class="p">,</span> <span class="n">x</span><span class="p">)</span>
<span class="n">neighbors</span> <span class="o">=</span> <span class="k">yield from</span> <span class="n">count_neighbors</span><span class="p">(</span><span class="n">y</span><span class="p">,</span> <span class="n">x</span><span class="p">)</span>
<span class="n">next_state</span> <span class="o">=</span> <span class="n">game_logic</span><span class="p">(</span><span class="n">state</span><span class="p">,</span> <span class="n">neighbors</span><span class="p">)</span>
<span class="k">yield</span> <span class="n">Transition</span><span class="p">(</span><span class="n">y</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">next_state</span><span class="p">)</span>
</pre></div>
<p>Importantly, the call to <code>count_neighbors</code> uses the <code>yield from</code> expression. This expression allows Python to compose generator coroutines together, making it easy to reuse smaller pieces of functionality and build complex coroutines from simpler ones. When <code>count_neighbors</code> is exhausted, the final value it returns (with the <code>return</code> statement) will be passed to <code>step_cell</code> as the result of the <code>yield from</code> expression.</p>
<p>Now I can finally define the simple game logic for Conway&#8217;s Game of Life. There are only three&nbsp;rules.</p>
<div class="highlight"><pre><span class="k">def</span> <span class="nf">game_logic</span><span class="p">(</span><span class="n">state</span><span class="p">,</span> <span class="n">neighbors</span><span class="p">):</span>
<span class="k">if</span> <span class="n">state</span> <span class="o">==</span> <span class="n">ALIVE</span><span class="p">:</span>
<span class="k">if</span> <span class="n">neighbors</span> <span class="o">&lt;</span> <span class="mi">2</span><span class="p">:</span>
<span class="k">return</span> <span class="n">EMPTY</span> <span class="c"># Die: Too few</span>
<span class="k">elif</span> <span class="n">neighbors</span> <span class="o">&gt;</span> <span class="mi">3</span><span class="p">:</span>
<span class="k">return</span> <span class="n">EMPTY</span> <span class="c"># Die: Too many</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">if</span> <span class="n">neighbors</span> <span class="o">==</span> <span class="mi">3</span><span class="p">:</span>
<span class="k">return</span> <span class="n">ALIVE</span> <span class="c"># Regenerate</span>
<span class="k">return</span> <span class="n">state</span>
</pre></div>
<p>I can drive the <code>step_cell</code> with fake data to test&nbsp;it.</p>
<div class="highlight"><pre><span class="n">it</span> <span class="o">=</span> <span class="n">step_cell</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span> <span class="mi">5</span><span class="p">)</span>
<span class="n">q0</span> <span class="o">=</span> <span class="nb">next</span><span class="p">(</span><span class="n">it</span><span class="p">)</span> <span class="c"># Initial location query</span>
<span class="k">print</span><span class="p">(</span><span class="s">&#39;Me: &#39;</span><span class="p">,</span> <span class="n">q0</span><span class="p">)</span>
<span class="n">q1</span> <span class="o">=</span> <span class="n">it</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="n">ALIVE</span><span class="p">)</span> <span class="c"># Send my status, get neighbor query</span>
<span class="k">print</span><span class="p">(</span><span class="s">&#39;Q1: &#39;</span><span class="p">,</span> <span class="n">q1</span><span class="p">)</span>
<span class="c"># ...</span>
<span class="n">t1</span> <span class="o">=</span> <span class="n">it</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="n">EMPTY</span><span class="p">)</span> <span class="c"># Send for q8, get game decision</span>
<span class="k">print</span><span class="p">(</span><span class="s">&#39;Outcome: &#39;</span><span class="p">,</span> <span class="n">t1</span><span class="p">)</span>
</pre></div>
<div class="highlight"><pre>&gt;&gt;&gt;
Me: Query(y=10, x=5)
Q1: Query(y=11, x=5)
...
Outcome: Transition(y=10, x=5, state=&#39;-&#39;)
</pre></div>
<p>The goal of the game is to run this logic for a whole grid of cells in lockstep. To do this, I can further compose the <code>step_cell</code> coroutine into a <code>simulate</code> coroutine. This coroutine progresses the grid of cells forward by yielding from <code>step_cell</code> many times. After progressing every coordinate, it yields a <code>TICK</code> object to indicate that the current generation of cells have all&nbsp;transitioned.</p>
<div class="highlight"><pre><span class="n">TICK</span> <span class="o">=</span> <span class="nb">object</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">simulate</span><span class="p">(</span><span class="n">height</span><span class="p">,</span> <span class="n">width</span><span class="p">):</span>
<span class="k">while</span> <span class="bp">True</span><span class="p">:</span>
<span class="k">for</span> <span class="n">y</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">height</span><span class="p">):</span>
<span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">width</span><span class="p">):</span>
<span class="k">yield from</span> <span class="n">step_cell</span><span class="p">(</span><span class="n">y</span><span class="p">,</span> <span class="n">x</span><span class="p">)</span>
<span class="k">yield</span> <span class="n">TICK</span>
</pre></div>
<p>What&#8217;s impressive about <code>simulate</code> is that it&#8217;s completely disconnected from the surrounding environment. I still haven&#8217;t defined how the grid is represented in Python objects, how <code>Query</code>, <code>Transition</code>, and <code>TICK</code> values are handled on the outside, nor how the game gets its initial state. But the logic is clear. Each cell will transition by running <code>step_cell</code>. Then the game clock will tick. This will continue forever, as long as the <code>simulate</code> coroutine is&nbsp;advanced.</p>
<p>This is the beauty of coroutines. They help you focus on the logic of what you&#8217;re trying to accomplish. They decouple your code&#8217;s instructions for the environment from the implementation that carries out your wishes. This enables you to run coroutines seemingly in parallel. This also allows you to improve the implementation of following those instructions over time without changing the&nbsp;coroutines.</p>
<p>Now I want to run <code>simulate</code> in a real environment. To do that, I need to represent the state of each cell in the grid. Here I define a class to contain the&nbsp;grid.</p>
<div class="highlight"><pre><span class="k">class</span> <span class="nc">Grid</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">height</span><span class="p">,</span> <span class="n">width</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">height</span> <span class="o">=</span> <span class="n">height</span>
<span class="bp">self</span><span class="o">.</span><span class="n">width</span> <span class="o">=</span> <span class="n">width</span>
<span class="bp">self</span><span class="o">.</span><span class="n">rows</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">height</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">rows</span><span class="o">.</span><span class="n">append</span><span class="p">([</span><span class="n">EMPTY</span><span class="p">]</span> <span class="o">*</span> <span class="bp">self</span><span class="o">.</span><span class="n">width</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="c"># ...</span>
</pre></div>
<p>The grid allows you to get and set the value of any coordinate. Coordinates that are out of bounds will wrap around, making the the grid act like infinite looping&nbsp;space.</p>
<div class="highlight"><pre> <span class="k">def</span> <span class="nf">query</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">x</span><span class="p">):</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">rows</span><span class="p">[</span><span class="n">y</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">height</span><span class="p">][</span><span class="n">x</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">width</span><span class="p">]</span>
<span class="k">def</span> <span class="nf">assign</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">state</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">rows</span><span class="p">[</span><span class="n">y</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">height</span><span class="p">][</span><span class="n">x</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">width</span><span class="p">]</span> <span class="o">=</span> <span class="n">state</span>
</pre></div>
<p>At last, I can define the function that interprets the values yielded from <code>simulate</code> and all of its interior coroutines. This function turns the instructions from the coroutines into interactions with the surrounding environment. It progresses the whole grid of cells forward a single step and then returns a new grid containing the next&nbsp;state.</p>
<div class="highlight"><pre><span class="k">def</span> <span class="nf">live_a_generation</span><span class="p">(</span><span class="n">grid</span><span class="p">,</span> <span class="n">sim</span><span class="p">):</span>
<span class="n">progeny</span> <span class="o">=</span> <span class="n">Grid</span><span class="p">(</span><span class="n">grid</span><span class="o">.</span><span class="n">height</span><span class="p">,</span> <span class="n">grid</span><span class="o">.</span><span class="n">width</span><span class="p">)</span>
<span class="n">item</span> <span class="o">=</span> <span class="nb">next</span><span class="p">(</span><span class="n">sim</span><span class="p">)</span>
<span class="k">while</span> <span class="n">item</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">TICK</span><span class="p">:</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">item</span><span class="p">,</span> <span class="n">Query</span><span class="p">):</span>
<span class="n">state</span> <span class="o">=</span> <span class="n">grid</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="n">item</span><span class="o">.</span><span class="n">y</span><span class="p">,</span> <span class="n">item</span><span class="o">.</span><span class="n">x</span><span class="p">)</span>
<span class="n">item</span> <span class="o">=</span> <span class="n">sim</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="n">state</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span> <span class="c"># Must be a Transition</span>
<span class="n">progeny</span><span class="o">.</span><span class="n">assign</span><span class="p">(</span><span class="n">item</span><span class="o">.</span><span class="n">y</span><span class="p">,</span> <span class="n">item</span><span class="o">.</span><span class="n">x</span><span class="p">,</span> <span class="n">item</span><span class="o">.</span><span class="n">state</span><span class="p">)</span>
<span class="n">item</span> <span class="o">=</span> <span class="nb">next</span><span class="p">(</span><span class="n">sim</span><span class="p">)</span>
<span class="k">return</span> <span class="n">progeny</span>
</pre></div>
<p>To see this function in action, I need to create a grid and set its initial state. Here I make a classic shape called a&nbsp;glider.</p>
<div class="highlight"><pre><span class="n">grid</span> <span class="o">=</span> <span class="n">Grid</span><span class="p">(</span><span class="mi">5</span><span class="p">,</span> <span class="mi">9</span><span class="p">)</span>
<span class="n">grid</span><span class="o">.</span><span class="n">assign</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="n">ALIVE</span><span class="p">)</span>
<span class="c"># ...</span>
<span class="k">print</span><span class="p">(</span><span class="n">grid</span><span class="p">)</span>
</pre></div>
<div class="highlight"><pre>&gt;&gt;&gt;
---*-----
----*----
--***----
---------
---------
</pre></div>
<p>Now I can progress this grid forward one generation at a time. You can see how the glider moves down and to the right on the grid based on the simple rules from the <code>game_logic</code> function.</p>
<div class="highlight"><pre><span class="k">class</span> <span class="nc">ColumnPrinter</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="c"># ...</span>
<span class="n">columns</span> <span class="o">=</span> <span class="n">ColumnPrinter</span><span class="p">()</span>
<span class="n">sim</span> <span class="o">=</span> <span class="n">simulate</span><span class="p">(</span><span class="n">grid</span><span class="o">.</span><span class="n">height</span><span class="p">,</span> <span class="n">grid</span><span class="o">.</span><span class="n">width</span><span class="p">)</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">5</span><span class="p">):</span>
<span class="n">columns</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">grid</span><span class="p">))</span>
<span class="n">grid</span> <span class="o">=</span> <span class="n">live_a_generation</span><span class="p">(</span><span class="n">grid</span><span class="p">,</span> <span class="n">sim</span><span class="p">)</span>
<span class="k">print</span><span class="p">(</span><span class="n">columns</span><span class="p">)</span>
</pre></div>
<div class="highlight"><pre>&gt;&gt;&gt;
0 | 1 | 2 | 3 | 4
---*----- | --------- | --------- | --------- | ---------
----*---- | --*-*---- | ----*---- | ---*----- | ----*----
--***---- | ---**---- | --*-*---- | ----**--- | -----*---
--------- | ---*----- | ---**---- | ---**---- | ---***---
--------- | --------- | --------- | --------- | ---------
</pre></div>
<p>The best part about this approach is that I can change the <code>game_logic</code> function without having to update the code that surrounds it. I can change the rules or add larger spheres of influence with the existing mechanics of <code>Query</code>, <code>Transition</code>, and <code>TICK</code>. This demonstrates how coroutines enable the separation of concerns, which is an important design&nbsp;principle.</p>
<h3>Coroutines in Python&nbsp;2</h3>
<p>Unfortunately, Python 2 is missing some of the syntactical sugar that makes coroutines so elegant in Python 3. There are two limitations. First, there is no <code>yield from</code> expression. That means when you want to compose generator coroutines in Python 2, you need to include an additional loop at the delegation&nbsp;point.</p>
<div class="highlight"><pre><span class="c"># Python 2</span>
<span class="k">def</span> <span class="nf">delegated</span><span class="p">():</span>
<span class="k">yield</span> <span class="mi">1</span>
<span class="k">yield</span> <span class="mi">2</span>
<span class="k">def</span> <span class="nf">composed</span><span class="p">():</span>
<span class="k">yield</span> <span class="s">&#39;A&#39;</span>
<span class="k">for</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">delegated</span><span class="p">():</span> <span class="c"># yield from in Python 3</span>
<span class="k">yield</span> <span class="n">value</span>
<span class="k">yield</span> <span class="s">&#39;B&#39;</span>
<span class="k">print</span> <span class="nb">list</span><span class="p">(</span><span class="n">composed</span><span class="p">())</span>
</pre></div>
<div class="highlight"><pre>&gt;&gt;&gt;
[&#39;A&#39;, 1, 2, &#39;B&#39;]
</pre></div>
<p>The second limitation is that there is no support for the <code>return</code> statement in Python 2 generators. To get the same behavior that interacts correctly with <code>try</code>/<code>except</code>/<code>finally</code> blocks, you need to define your own exception type and raise it when you want to return a&nbsp;value.</p>
<div class="highlight"><pre><span class="c"># Python 2</span>
<span class="k">class</span> <span class="nc">MyReturn</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">value</span> <span class="o">=</span> <span class="n">value</span>
<span class="k">def</span> <span class="nf">delegated</span><span class="p">():</span>
<span class="k">yield</span> <span class="mi">1</span>
<span class="k">raise</span> <span class="n">MyReturn</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span> <span class="c"># return 2 in Python 3</span>
<span class="k">yield</span> <span class="s">&#39;Not reached&#39;</span>
<span class="k">def</span> <span class="nf">composed</span><span class="p">():</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">for</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">delegated</span><span class="p">():</span>
<span class="k">yield</span> <span class="n">value</span>
<span class="k">except</span> <span class="n">MyReturn</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="n">output</span> <span class="o">=</span> <span class="n">e</span><span class="o">.</span><span class="n">value</span>
<span class="k">yield</span> <span class="n">output</span> <span class="o">*</span> <span class="mi">4</span>
<span class="k">print</span> <span class="nb">list</span><span class="p">(</span><span class="n">composed</span><span class="p">())</span>
</pre></div>
<div class="highlight"><pre>&gt;&gt;&gt;
[1, 8]
</pre></div>
<h3>Things to&nbsp;Remember</h3>
<ul>
<li>Coroutines provide an efficient way to run tens of thousands of functions seemingly at the same&nbsp;time.</li>
<li>Within a generator, the value of the <code>yield</code> expression will be whatever value was passed to the generator&#8217;s <code>send</code> method from the exterior&nbsp;code.</li>
<li>Coroutines give you a powerful tool for separating the core logic of your program from its interaction with the surrounding&nbsp;environment.</li>
<li>Python 2 doesn&#8217;t support <code>yield from</code> or <code>return</code> within&nbsp;generators.</li>
</ul></summary></entry><entry><title>The Book Is Published</title><link href="http://www.effectivepython.com/2015/03/06/books-is-published/" rel="alternate"></link><updated>2015-03-06T14:00:00-08:00</updated><author><name>Brett Slatkin</name></author><id>tag:www.effectivepython.com,2015-03-06:2015/03/06/books-is-published/</id><summary type="html"><p>Printed, physical copies of the <em>Effective Python</em> book are now for sale! <a href="http://goo.gl/mpVxz2">Follow this link to buy directly from the publisher</a> (free shipping in the <span class="caps">USA</span>). The publisher also has ePub and <span class="caps">PDF</span> versions available. <a href="http://amzn.to/1ylkKmc">Follow this link to buy from Amazon</a>. Amazon also has a Kindle edition&nbsp;available.</p></summary></entry><entry><title>Digital Editions Now Available</title><link href="http://www.effectivepython.com/2015/02/15/digital-editions-now-available/" rel="alternate"></link><updated>2015-02-15T13:00:00-08:00</updated><author><name>Brett Slatkin</name></author><id>tag:www.effectivepython.com,2015-02-15:2015/02/15/digital-editions-now-available/</id><summary type="html"><p>Digital editions of <em>Effective Python</em> are now available. <a href="http://click.linksynergy.com/link?id=YvEWtFaKGwg&amp;offerid=145238.2235742&amp;type=2&amp;murl=http%3A%2F%2Fwww.informit.com%2Ftitle%2F9780134034423">Follow this link to buy the ePub or <span class="caps">PDF</span> version</a>. <a href="http://amzn.to/1AFwumA">Follow this link to buy the Kindle edition</a>. The print copy is due out on March&nbsp;6th.</p></summary></entry><entry><title>Item 23: Accept Functions for Simple Interfaces Instead of Classes</title><link href="http://www.effectivepython.com/2015/02/12/accept-functions-for-simple-interfaces-instead-of-classes/" rel="alternate"></link><updated>2015-02-12T10:20:00-08:00</updated><author><name>Brett Slatkin</name></author><id>tag:www.effectivepython.com,2015-02-12:2015/02/12/accept-functions-for-simple-interfaces-instead-of-classes/</id><summary type="html"><p><em>The following is a sample from the new book <a href="/">Effective Python</a>.</em><br><br></p>
<p>Many of Python&#8217;s built-in APIs allow you to customize behavior by passing in a function. These <em>hooks</em> are used by APIs to call back your code while they execute. For example, the <code>list</code> type&#8217;s <code>sort</code> method takes an optional <code>key</code> argument that&#8217;s used to determine each index&#8217;s value for sorting. Here I sort a list of names based on their lengths by providing a <code>lambda</code> expression as the <code>key</code> hook.</p>
<div class="highlight"><pre><span class="n">names</span> <span class="o">=</span> <span class="p">[</span><span class="s">&#39;Socrates&#39;</span><span class="p">,</span> <span class="s">&#39;Archimedes&#39;</span><span class="p">,</span> <span class="s">&#39;Plato&#39;</span><span class="p">,</span> <span class="s">&#39;Aristotle&#39;</span><span class="p">]</span>
<span class="n">names</span><span class="o">.</span><span class="n">sort</span><span class="p">(</span><span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">x</span><span class="p">:</span> <span class="nb">len</span><span class="p">(</span><span class="n">x</span><span class="p">))</span>
<span class="k">print</span><span class="p">(</span><span class="n">names</span><span class="p">)</span>
</pre></div>
<div class="highlight"><pre>&gt;&gt;&gt;
[&#39;Plato&#39;, &#39;Socrates&#39;, &#39;Aristotle&#39;, &#39;Archimedes&#39;]
</pre></div>
<p>In other languages, you might expect hooks to be defined by an abstract class. In Python, many hooks are just stateless functions with well-defined arguments and return values. Functions are ideal for hooks because they are easier to describe and simpler to define than classes. Functions work as hooks because Python has <em>first-class</em> functions: Functions and methods can be passed around and referenced like any other value in the&nbsp;language.</p>
<p>For example, say you want to customize the behavior of the <code>defaultdict</code> class. This data structure allows you to supply a function that will be called each time a missing key is accessed. The function must return the default value the missing key should have in the dictionary. Here I define a hook that logs each time a key is missing and returns <code>0</code> for the default&nbsp;value.</p>
<div class="highlight"><pre><span class="k">def</span> <span class="nf">log_missing</span><span class="p">():</span>
<span class="k">print</span><span class="p">(</span><span class="s">&#39;Key added&#39;</span><span class="p">)</span>
<span class="k">return</span> <span class="mi">0</span>
</pre></div>
<p>Given an initial dictionary and a set of desired increments, I can cause the <code>log_missing</code> function to run and print twice (for <code>'red'</code> and <code>'orange'</code>).</p>
<div class="highlight"><pre><span class="n">current</span> <span class="o">=</span> <span class="p">{</span><span class="s">&#39;green&#39;</span><span class="p">:</span> <span class="mi">12</span><span class="p">,</span> <span class="s">&#39;blue&#39;</span><span class="p">:</span> <span class="mi">3</span><span class="p">}</span>
<span class="n">increments</span> <span class="o">=</span> <span class="p">[</span>
<span class="p">(</span><span class="s">&#39;red&#39;</span><span class="p">,</span> <span class="mi">5</span><span class="p">),</span>
<span class="p">(</span><span class="s">&#39;blue&#39;</span><span class="p">,</span> <span class="mi">17</span><span class="p">),</span>
<span class="p">(</span><span class="s">&#39;orange&#39;</span><span class="p">,</span> <span class="mi">9</span><span class="p">),</span>
<span class="p">]</span>
<span class="n">result</span> <span class="o">=</span> <span class="n">defaultdict</span><span class="p">(</span><span class="n">log_missing</span><span class="p">,</span> <span class="n">current</span><span class="p">)</span>
<span class="k">print</span><span class="p">(</span><span class="s">&#39;Before:&#39;</span><span class="p">,</span> <span class="nb">dict</span><span class="p">(</span><span class="n">result</span><span class="p">))</span>
<span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">amount</span> <span class="ow">in</span> <span class="n">increments</span><span class="p">:</span>
<span class="n">result</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">+=</span> <span class="n">amount</span>
<span class="k">print</span><span class="p">(</span><span class="s">&#39;After: &#39;</span><span class="p">,</span> <span class="nb">dict</span><span class="p">(</span><span class="n">result</span><span class="p">))</span>
</pre></div>
<div class="highlight"><pre>&gt;&gt;&gt;
Before: {&#39;blue&#39;: 3, &#39;green&#39;: 12}
Key added
Key added
After: {&#39;red&#39;: 5, &#39;green&#39;: 12, &#39;blue&#39;: 20, &#39;orange&#39;: 9}
</pre></div>
<p>Supplying functions like <code>log_missing</code> makes APIs easy to build and test because it separates side effects from deterministic behavior. For example, say you now want the default value hook passed to <code>defaultdict</code> to count the total number of keys that were missing. One way to achieve this is using a stateful closure (see [Item 15 for details). Here I define a helper function that uses such a closure as the default value&nbsp;hook.</p>
<div class="highlight"><pre><span class="k">def</span> <span class="nf">increment_with_report</span><span class="p">(</span><span class="n">current</span><span class="p">,</span> <span class="n">increments</span><span class="p">):</span>
<span class="n">added_count</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">def</span> <span class="nf">missing</span><span class="p">():</span>
<span class="n">nonlocal</span> <span class="n">added_count</span> <span class="c"># Stateful closure</span>
<span class="n">added_count</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="k">return</span> <span class="mi">0</span>
<span class="n">result</span> <span class="o">=</span> <span class="n">defaultdict</span><span class="p">(</span><span class="n">missing</span><span class="p">,</span> <span class="n">current</span><span class="p">)</span>
<span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">amount</span> <span class="ow">in</span> <span class="n">increments</span><span class="p">:</span>
<span class="n">result</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">+=</span> <span class="n">amount</span>
<span class="k">return</span> <span class="n">result</span><span class="p">,</span> <span class="n">added_count</span>
</pre></div>
<p>Running this function produces the expected result (<code>2</code>), even though the <code>defaultdict</code> has no idea that the <code>missing</code> hook maintains state. This is another benefit of accepting simple functions for interfaces. It&#8217;s easy to add functionality later by hiding state in a&nbsp;closure.</p>
<div class="highlight"><pre><span class="n">result</span><span class="p">,</span> <span class="n">count</span> <span class="o">=</span> <span class="n">increment_with_report</span><span class="p">(</span><span class="n">current</span><span class="p">,</span> <span class="n">increments</span><span class="p">)</span>
<span class="k">assert</span> <span class="n">count</span> <span class="o">==</span> <span class="mi">2</span>
</pre></div>
<p>The problem with defining a closure for stateful hooks is that it&#8217;s harder to read than the stateless function example. Another approach is to define a small class that encapsulates the state you want to&nbsp;track.</p>
<div class="highlight"><pre><span class="k">class</span> <span class="nc">CountMissing</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">added</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">def</span> <span class="nf">missing</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">added</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="k">return</span> <span class="mi">0</span>
</pre></div>
<p>In other languages, you might expect that now <code>defaultdict</code> would have to be modified to accommodate the interface of <code>CountMissing</code>. But in Python, thanks to first-class functions, you can reference the <code>CountMissing.missing</code> method directly on an object and pass it to <code>defaultdict</code> as the default value hook. It&#8217;s trivial to have a method satisfy a function&nbsp;interface.</p>
<div class="highlight"><pre><span class="n">counter</span> <span class="o">=</span> <span class="n">CountMissing</span><span class="p">()</span>
<span class="n">result</span> <span class="o">=</span> <span class="n">defaultdict</span><span class="p">(</span><span class="n">counter</span><span class="o">.</span><span class="n">missing</span><span class="p">,</span> <span class="n">current</span><span class="p">)</span> <span class="c"># Method reference</span>
<span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">amount</span> <span class="ow">in</span> <span class="n">increments</span><span class="p">:</span>
<span class="n">result</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">+=</span> <span class="n">amount</span>
<span class="k">assert</span> <span class="n">counter</span><span class="o">.</span><span class="n">added</span> <span class="o">==</span> <span class="mi">2</span>
</pre></div>
<p>Using a helper class like this to provide the behavior of a stateful closure is clearer than the <code>increment_with_report</code> function above. However, in isolation it&#8217;s still not immediately obvious what the purpose of the <code>CountMissing</code> class is. Who constructs a <code>CountMissing</code> object? Who calls the <code>missing</code> method? Will the class need other public methods to be added in the future? Until you see its usage with <code>defaultdict</code> the class is a&nbsp;mystery.</p>
<p>To clarify this situation, Python allows classes to define the <code>__call__</code> special method. <code>__call__</code> allows an object to be called just like a function. It also causes the <code>callable</code> built-in function to return <code>True</code> for such an&nbsp;instance.</p>
<div class="highlight"><pre><span class="k">class</span> <span class="nc">BetterCountMissing</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">added</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">def</span> <span class="nf">__call__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">added</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="k">return</span> <span class="mi">0</span>
<span class="n">counter</span> <span class="o">=</span> <span class="n">BetterCountMissing</span><span class="p">()</span>
<span class="n">counter</span><span class="p">()</span>
<span class="k">assert</span> <span class="nb">callable</span><span class="p">(</span><span class="n">counter</span><span class="p">)</span>
</pre></div>
<p>Here I use a <code>BetterCountMissing</code> instance as the default value hook for a <code>defaultdict</code> to track the number of missing keys that were&nbsp;added.</p>
<div class="highlight"><pre><span class="n">counter</span> <span class="o">=</span> <span class="n">BetterCountMissing</span><span class="p">()</span>
<span class="n">result</span> <span class="o">=</span> <span class="n">defaultdict</span><span class="p">(</span><span class="n">counter</span><span class="p">,</span> <span class="n">current</span><span class="p">)</span> <span class="c"># Relies on __call__</span>
<span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">amount</span> <span class="ow">in</span> <span class="n">increments</span><span class="p">:</span>
<span class="n">result</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">+=</span> <span class="n">amount</span>
<span class="k">assert</span> <span class="n">counter</span><span class="o">.</span><span class="n">added</span> <span class="o">==</span> <span class="mi">2</span>
</pre></div>
<p>This is much clearer than the <code>CountMissing.missing</code> example. The <code>__call__</code> method indicates that a class&#8217;s instances will be used somewhere a function argument would also be suitable (like <span class="caps">API</span> hooks). It directs new readers of the code to the entry point that&#8217;s responsible for the class&#8217;s primary behavior. It provides a strong hint that the goal of the class is to act as a stateful&nbsp;closure.</p>
<p>Best of all, <code>defaultdict</code> still has no view into what&#8217;s going on when you use <code>__call__</code>. All that <code>defaultdict</code> requires is a function for the default value hook. Python provides many different ways to satisfy a simple function interface depending on what you need to&nbsp;accomplish.</p>
<h3>Things to&nbsp;Remember</h3>
<ul>
<li>Instead of defining and instantiating classes, functions are often all you need for simple interfaces between components in&nbsp;Python.</li>
<li>References to functions and methods in Python are first-class, meaning they can be used in expressions like any other&nbsp;type.</li>
<li>The <code>__call__</code> special method enables instances of a class to be called like plain Python&nbsp;functions.</li>
<li>When you need a function to maintain state, consider defining a class that provides the <code>__call__</code> method instead of defining a stateful&nbsp;closure.</li>
</ul></summary></entry><entry><title>Item 34: Register Class Existence with Metaclasses</title><link href="http://www.effectivepython.com/2015/02/02/register-class-existence-with-metaclasses/" rel="alternate"></link><updated>2015-02-02T22:22:00-08:00</updated><author><name>Brett Slatkin</name></author><id>tag:www.effectivepython.com,2015-02-02:2015/02/02/register-class-existence-with-metaclasses/</id><summary type="html"><p><em>The following is a sample from the new book <a href="/">Effective Python</a>.</em><br><br></p>
<p>A common use of metaclasses is to automatically register types in your program. Registration is useful for doing reverse lookups, where you need to map a simple identifier back to a corresponding class.</p>
<p>For example, say you want to implement your own serialized representation of a Python object using <span class="caps">JSON</span>. You need a way to take an object and turn it into a <span class="caps">JSON</span> string. Here I do this generically by defining a base class that records the constructor parameters and turns them into a <span class="caps">JSON</span>&nbsp;dictionary.</p>
<div class="highlight"><pre><span class="k">class</span> <span class="nc">Serializable</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">args</span> <span class="o">=</span> <span class="n">args</span>
<span class="k">def</span> <span class="nf">serialize</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">({</span><span class="s">&#39;args&#39;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">args</span><span class="p">})</span>
</pre></div>
<p>This class makes it easy to serialize simple, immutable data structures like <code>Point2D</code> to a&nbsp;string.</p>
<div class="highlight"><pre><span class="k">class</span> <span class="nc">Point2D</span><span class="p">(</span><span class="n">Serializable</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">):</span>
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">x</span> <span class="o">=</span> <span class="n">x</span>
<span class="bp">self</span><span class="o">.</span><span class="n">y</span> <span class="o">=</span> <span class="n">y</span>
<span class="k">def</span> <span class="nf">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="s">&#39;Point2D(</span><span class="si">%d</span><span class="s">, </span><span class="si">%d</span><span class="s">)&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">y</span><span class="p">)</span>
<span class="n">point</span> <span class="o">=</span> <span class="n">Point2D</span><span class="p">(</span><span class="mi">5</span><span class="p">,</span> <span class="mi">3</span><span class="p">)</span>
<span class="k">print</span><span class="p">(</span><span class="s">&#39;Object: &#39;</span><span class="p">,</span> <span class="n">point</span><span class="p">)</span>
<span class="k">print</span><span class="p">(</span><span class="s">&#39;Serialized:&#39;</span><span class="p">,</span> <span class="n">point</span><span class="o">.</span><span class="n">serialize</span><span class="p">())</span>
</pre></div>
<div class="highlight"><pre>&gt;&gt;&gt;
Object: Point2D(5, 3)
Serialized: {&quot;args&quot;: [5, 3]}
</pre></div>
<p>Now I need to deserialize this <span class="caps">JSON</span> string and construct the <code>Point2D</code> object it represents. Here I define another class that can deserialize the data from its <code>Serializable</code> parent&nbsp;class.</p>
<div class="highlight"><pre><span class="k">class</span> <span class="nc">Deserializable</span><span class="p">(</span><span class="n">Serializable</span><span class="p">):</span>
<span class="nd">@classmethod</span>
<span class="k">def</span> <span class="nf">deserialize</span><span class="p">(</span><span class="n">cls</span><span class="p">,</span> <span class="n">json_data</span><span class="p">):</span>
<span class="n">params</span> <span class="o">=</span> <span class="n">json</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">json_data</span><span class="p">)</span>
<span class="k">return</span> <span class="n">cls</span><span class="p">(</span><span class="o">*</span><span class="n">params</span><span class="p">[</span><span class="s">&#39;args&#39;</span><span class="p">])</span>
</pre></div>
<p>Using <code>Deserializable</code> makes it easy to serialize and deserialize simple, immutable objects in a generic&nbsp;way.</p>
<div class="highlight"><pre><span class="k">class</span> <span class="nc">BetterPoint2D</span><span class="p">(</span><span class="n">Deserializable</span><span class="p">):</span>
<span class="c"># ...</span>
<span class="n">point</span> <span class="o">=</span> <span class="n">BetterPoint2D</span><span class="p">(</span><span class="mi">5</span><span class="p">,</span> <span class="mi">3</span><span class="p">)</span>
<span class="k">print</span><span class="p">(</span><span class="s">&#39;Before: &#39;</span><span class="p">,</span> <span class="n">point</span><span class="p">)</span>
<span class="n">data</span> <span class="o">=</span> <span class="n">point</span><span class="o">.</span><span class="n">serialize</span><span class="p">()</span>
<span class="k">print</span><span class="p">(</span><span class="s">&#39;Serialized:&#39;</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span>
<span class="n">after</span> <span class="o">=</span> <span class="n">BetterPoint2D</span><span class="o">.</span><span class="n">deserialize</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
<span class="k">print</span><span class="p">(</span><span class="s">&#39;After: &#39;</span><span class="p">,</span> <span class="n">after</span><span class="p">)</span>
</pre></div>
<div class="highlight"><pre>&gt;&gt;&gt;
Before: BetterPoint2D(5, 3)
Serialized: {&quot;args&quot;: [5, 3]}
After: BetterPoint2D(5, 3)
</pre></div>
<p>The problem with this approach is it only works if you know the intended type of the serialized data ahead of time (e.g., <code>Point2D</code>, <code>BetterPoint2D</code>). Ideally you&#8217;d have a large number of classes serializing to <span class="caps">JSON</span> and one common function that could deserialize any of them back to a corresponding Python&nbsp;object.</p>
<p>To do this, I can include the serialized object&#8217;s class name in the <span class="caps">JSON</span>&nbsp;data.</p>
<div class="highlight"><pre><span class="k">class</span> <span class="nc">BetterSerializable</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">args</span> <span class="o">=</span> <span class="n">args</span>
<span class="k">def</span> <span class="nf">serialize</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">({</span>
<span class="s">&#39;class&#39;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">__class__</span><span class="o">.</span><span class="n">__name__</span><span class="p">,</span>
<span class="s">&#39;args&#39;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">args</span><span class="p">,</span>
<span class="p">})</span>
<span class="k">def</span> <span class="nf">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="c"># ...</span>
</pre></div>
<p>Then I can maintain a mapping of class names back to constructors for those objects. The general <code>deserialize</code> function will work for any classes passed to <code>register_class</code>.</p>
<div class="highlight"><pre><span class="n">registry</span> <span class="o">=</span> <span class="p">{}</span>
<span class="k">def</span> <span class="nf">register_class</span><span class="p">(</span><span class="n">target_class</span><span class="p">):</span>
<span class="n">registry</span><span class="p">[</span><span class="n">target_class</span><span class="o">.</span><span class="n">__name__</span><span class="p">]</span> <span class="o">=</span> <span class="n">target_class</span>
<span class="k">def</span> <span class="nf">deserialize</span><span class="p">(</span><span class="n">data</span><span class="p">):</span>
<span class="n">params</span> <span class="o">=</span> <span class="n">json</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
<span class="n">name</span> <span class="o">=</span> <span class="n">params</span><span class="p">[</span><span class="s">&#39;class&#39;</span><span class="p">]</span>
<span class="n">target_class</span> <span class="o">=</span> <span class="n">registry</span><span class="p">[</span><span class="n">name</span><span class="p">]</span>
<span class="k">return</span> <span class="n">target_class</span><span class="p">(</span><span class="o">*</span><span class="n">params</span><span class="p">[</span><span class="s">&#39;args&#39;</span><span class="p">])</span>
</pre></div>
<p>To ensure <code>deserialize</code> always works properly, I must call <code>register_class</code> for every class I may want to deserialize in the&nbsp;future.</p>
<div class="highlight"><pre><span class="k">class</span> <span class="nc">EvenBetterPoint2D</span><span class="p">(</span><span class="n">BetterSerializable</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">):</span>
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">x</span> <span class="o">=</span> <span class="n">x</span>
<span class="bp">self</span><span class="o">.</span><span class="n">y</span> <span class="o">=</span> <span class="n">y</span>
<span class="n">register_class</span><span class="p">(</span><span class="n">EvenBetterPoint2D</span><span class="p">)</span>
</pre></div>
<p>Now I can deserialize an arbitrary <span class="caps">JSON</span> string without having to know which class it&nbsp;contains.</p>
<div class="highlight"><pre><span class="n">point</span> <span class="o">=</span> <span class="n">EvenBetterPoint2D</span><span class="p">(</span><span class="mi">5</span><span class="p">,</span> <span class="mi">3</span><span class="p">)</span>
<span class="k">print</span><span class="p">(</span><span class="s">&#39;Before: &#39;</span><span class="p">,</span> <span class="n">point</span><span class="p">)</span>
<span class="n">data</span> <span class="o">=</span> <span class="n">point</span><span class="o">.</span><span class="n">serialize</span><span class="p">()</span>
<span class="k">print</span><span class="p">(</span><span class="s">&#39;Serialized:&#39;</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span>
<span class="n">after</span> <span class="o">=</span> <span class="n">deserialize</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
<span class="k">print</span><span class="p">(</span><span class="s">&#39;After: &#39;</span><span class="p">,</span> <span class="n">after</span><span class="p">)</span>
</pre></div>
<div class="highlight"><pre>&gt;&gt;&gt;
Before: EvenBetterPoint2D(5, 3)
Serialized: {&quot;class&quot;: &quot;EvenBetterPoint2D&quot;, &quot;args&quot;: [5, 3]}
After: EvenBetterPoint2D(5, 3)
</pre></div>
<p>The problem with this approach is that you can forget to call <code>register_class</code>.</p>
<div class="highlight"><pre><span class="k">class</span> <span class="nc">Point3D</span><span class="p">(</span><span class="n">BetterSerializable</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">z</span><span class="p">):</span>
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">z</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">x</span> <span class="o">=</span> <span class="n">x</span>
<span class="bp">self</span><span class="o">.</span><span class="n">y</span> <span class="o">=</span> <span class="n">y</span>
<span class="bp">self</span><span class="o">.</span><span class="n">z</span> <span class="o">=</span> <span class="n">z</span>
<span class="c"># Forgot to call register_class! Whoops!</span>
</pre></div>
<p>This will cause your code to break at runtime, when you finally try to deserialize an object of a class you forgot to&nbsp;register.</p>
<div class="highlight"><pre><span class="n">point</span> <span class="o">=</span> <span class="n">Point3D</span><span class="p">(</span><span class="mi">5</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="o">-</span><span class="mi">4</span><span class="p">)</span>
<span class="n">data</span> <span class="o">=</span> <span class="n">point</span><span class="o">.</span><span class="n">serialize</span><span class="p">()</span>
<span class="n">deserialize</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
</pre></div>
<div class="highlight"><pre>&gt;&gt;&gt;
KeyError: &#39;Point3D&#39;
</pre></div>
<p>Even though you chose to subclass <code>BetterSerializable</code>, you won&#8217;t actually get all of its features if you forget to call <code>register_class</code> after your <code>class</code> statement body. This approach is error prone and especially challenging for beginners. The same omission can happen with <em>class decorators</em> in Python&nbsp;3.</p>
<p>What if you could somehow act on the programmer&#8217;s intent to use <code>BetterSerializable</code> and ensure <code>register_class</code> is called in all cases? Metaclasses enable this by intercepting the <code>class</code> statement when subclasses are defined. This lets you register the new type immediately after the class&#8217;s&nbsp;body.</p>
<div class="highlight"><pre><span class="k">class</span> <span class="nc">Meta</span><span class="p">(</span><span class="nb">type</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">__new__</span><span class="p">(</span><span class="n">meta</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">bases</span><span class="p">,</span> <span class="n">class_dict</span><span class="p">):</span>
<span class="n">cls</span> <span class="o">=</span> <span class="nb">type</span><span class="o">.</span><span class="n">__new__</span><span class="p">(</span><span class="n">meta</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">bases</span><span class="p">,</span> <span class="n">class_dict</span><span class="p">)</span>
<span class="n">register_class</span><span class="p">(</span><span class="n">cls</span><span class="p">)</span>
<span class="k">return</span> <span class="n">cls</span>
<span class="k">class</span> <span class="nc">RegisteredSerializable</span><span class="p">(</span><span class="n">BetterSerializable</span><span class="p">,</span> <span class="n">metaclass</span><span class="o">=</span><span class="n">Meta</span><span class="p">):</span>
<span class="k">pass</span>
</pre></div>
<p>When I define a subclass of <code>RegisteredSerializable</code>, I can be confident that the call to <code>register_class</code> happened and <code>deserialize</code> will always work as&nbsp;expected.</p>
<div class="highlight"><pre><span class="k">class</span> <span class="nc">Vector3D</span><span class="p">(</span><span class="n">RegisteredSerializable</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">z</span><span class="p">):</span>
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">z</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">x</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">y</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">z</span> <span class="o">=</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">z</span>
<span class="n">v3</span> <span class="o">=</span> <span class="n">Vector3D</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span> <span class="o">-</span><span class="mi">7</span><span class="p">,</span> <span class="mi">3</span><span class="p">)</span>
<span class="k">print</span><span class="p">(</span><span class="s">&#39;Before: &#39;</span><span class="p">,</span> <span class="n">v3</span><span class="p">)</span>
<span class="n">data</span> <span class="o">=</span> <span class="n">v3</span><span class="o">.</span><span class="n">serialize</span><span class="p">()</span>
<span class="k">print</span><span class="p">(</span><span class="s">&#39;Serialized:&#39;</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span>
<span class="k">print</span><span class="p">(</span><span class="s">&#39;After: &#39;</span><span class="p">,</span> <span class="n">deserialize</span><span class="p">(</span><span class="n">data</span><span class="p">))</span>
</pre></div>
<div class="highlight"><pre>&gt;&gt;&gt;
Before: Vector3D(10, -7, 3)
Serialized: {&quot;class&quot;: &quot;Vector3D&quot;, &quot;args&quot;: [10, -7, 3]}
After: Vector3D(10, -7, 3)
</pre></div>
<p>Using metaclasses for class registration ensures that you&#8217;ll never miss a class as long as the inheritance tree is right. This works well for serialization, as I&#8217;ve shown, and also applies to Database ORMs, plug-in systems, and system&nbsp;hooks.</p>
<h3>Things to&nbsp;Remember</h3>
<ul>
<li>Class registration is a helpful pattern for building modular Python&nbsp;programs.</li>
<li>Metaclasses let you run registration code automatically each time your base class is subclassed in a&nbsp;program.</li>
<li>Using metaclasses for class registration avoids errors by ensuring that you never miss a registration&nbsp;call.</li>
</ul></summary></entry><entry><title>Item 53: Use Virtual Environments for Isolated and Reproducible Dependencies</title><link href="http://www.effectivepython.com/2015/01/21/use-virtual-environments-for-isolated-and-reproducible-dependencies/" rel="alternate"></link><updated>2015-01-21T19:45:00-08:00</updated><author><name>Brett Slatkin</name></author><id>tag:www.effectivepython.com,2015-01-21:2015/01/21/use-virtual-environments-for-isolated-and-reproducible-dependencies/</id><summary type="html"><p><em>The following is a sample from the new book <a href="/">Effective Python</a>.</em><br><br></p>
<p>Building larger and more complex programs often leads you to rely on various packages from the Python community. You&#8217;ll find yourself running <code>pip</code> to install packages like <code>pytz</code>, <code>numpy</code>, and many&nbsp;others.</p>
<p>The problem is that by default <code>pip</code> installs new packages in a global location. That causes all Python programs on your system to be affected by these installed modules. In theory, this shouldn&#8217;t be an issue. If you install a package and never <code>import</code> it, how could it affect your programs?</p>
<p>The trouble comes from transitive dependencies: the packages that the packages you install depend on. For example, you can see what the <code>Sphinx</code> package depends on after installing it by asking <code>pip</code>.</p>
<div class="highlight"><pre>$ pip3 show Sphinx
---
Name: Sphinx
Version: 1.2.2
Location: /usr/local/lib/python3.4/site-packages
Requires: docutils, Jinja2, Pygments
</pre></div>
<p>If you install another package like <code>flask</code>, you can see that it too depends on the <code>Jinja2</code> package.</p>
<div class="highlight"><pre>$ pip3 show flask
---
Name: Flask
Version: 0.10.1
Location: /usr/local/lib/python3.4/site-packages
Requires: Werkzeug, Jinja2, itsdangerous
</pre></div>
<p>The conflict arises as <code>Sphinx</code> and <code>flask</code> diverge over time. Perhaps right now they both require the same version of <code>Jinja2</code> and everything is fine. But six months or a year from now, <code>Jinja2</code> may release a new version that makes breaking changes to users of the library. If you update your global version of <code>Jinja2</code> with <code>pip install --upgrade</code>, you may find that <code>Sphinx</code> breaks while <code>flask</code> keeps&nbsp;working.</p>
<p>The cause of this breakage is that Python can only have a single global version of a module installed at a time. If one of your installed packages must use the new version and another package must use the old version, your system isn&#8217;t going to work&nbsp;properly.</p>
<p>Such breakage can even happen when package maintainers try their best to preserve <span class="caps">API</span> compatibility between releases. New versions of a library can subtly change behaviors that <span class="caps">API</span> consuming code relies on. Users on a system may upgrade one package to a new version but not others, breaking dependencies. There&#8217;s a constant risk of the ground moving beneath your&nbsp;feet.</p>
<p>These difficulties are magnified when you collaborate with other developers who do their work on separate computers. It&#8217;s reasonable to assume that the versions of Python and global packages they have installed on their machines will be slightly different than your own. This can cause frustrating situations where a codebase works perfectly on one programmer&#8217;s machine and is completely broken on&nbsp;another&#8217;s.</p>
<p>The solution to all of these problems is a tool called <code>pyvenv</code>, which provides <em>virtual environments</em>. Since Python 3.4, the <code>pyvenv</code> command-line tool is available by default along with the Python installation (it&#8217;s also accessible with <code>python -m venv</code>). Prior versions of Python require installing a separate package (with <code>pip install virtualenv</code>) and using a command-line tool called <code>virtualenv</code>.</p>
<p><code>pyvenv</code> allows you to create isolated versions of the Python environment. Using <code>pyvenv</code>, you can have many different versions of the same package installed on the same system at the same time without conflicts. This lets you work on many different projects and use many different tools on the same&nbsp;computer.</p>
<p><code>pyvenv</code> does this by installing explicit versions of packages and their dependencies into completely separate directory structures. This makes it possible to reproduce a Python environment that you know will work with your code. It&#8217;s a reliable way to avoid surprising&nbsp;breakages.</p>
<h3>The <code>pyvenv</code> Command</h3>
<p>Here&#8217;s a quick tutorial on how to use <code>pyvenv</code> effectively. Before using the tool, it&#8217;s important to note the meaning of the <code>python3</code> command-line on your system. On my computer, <code>python3</code> is located in the <code>/usr/local/bin</code> directory and evaluates to version&nbsp;3.4.2.</p>
<div class="highlight"><pre>$ which python3
/usr/local/bin/python3
$ python3 --version
Python 3.4.2
</pre></div>
<p>To demonstrate the setup of my environment, I can test that running a command to import the <code>pytz</code> module doesn&#8217;t cause an error. This works because I already have the <code>pytz</code> package installed as a global&nbsp;module.</p>
<div class="highlight"><pre>$ python3 -c &#39;import pytz&#39;
$
</pre></div>
<p>Now I use <code>pyvenv</code> to create a new virtual environment called <code>myproject</code>. Each virtual environment must live in its own unique directory. The result of the command is a tree of directories and&nbsp;files.</p>
<div class="highlight"><pre>$ pyvenv /tmp/myproject
$ cd /tmp/myproject
$ ls
bin include lib pyvenv.cfg
</pre></div>
<p>To start using the virtual environment, I use the <code>source</code> command from my shell on the <code>bin/activate</code> script. <code>activate</code> modifies all of my environment variables to match the virtual environment. It also updates my command-line prompt to include the virtual environment name (<code>'myproject'</code>) to make it extremely clear what I&#8217;m working&nbsp;on.</p>
<div class="highlight"><pre>$ source bin/activate
(myproject)$
</pre></div>
<p>After activation, you can see that the path to the <code>python3</code> command-line tool has moved to within the virtual environment&nbsp;directory.</p>
<div class="highlight"><pre>(myproject)$ which python3
/tmp/myproject/bin/python3
(myproject)$ ls -l /tmp/myproject/bin/python3
... -&gt; /tmp/myproject/bin/python3.4
(myproject)$ ls -l /tmp/myproject/bin/python3.4
... -&gt; /usr/local/bin/python3.4
</pre></div>
<p>This ensures that changes to the outside system will not affect the virtual environment. Even if the outer system upgrades its default <code>python3</code> to version 3.5, my virtual environment will still explicitly point at version&nbsp;3.4.</p>
<p>The virtual environment I created with <code>pyvenv</code> starts with no packages installed except for <code>pip</code> and <code>setuptools</code>. Trying to use the <code>pytz</code> package that was installed as a global module in the outside system will fail because it&#8217;s unknown to the virtual&nbsp;environment.</p>
<div class="highlight"><pre>(myproject)$ python3 -c &#39;import pytz&#39;
Traceback (most recent call last):
File &quot;&lt;string&gt;&quot;, line 1, in &lt;module&gt;
ImportError: No module named &#39;pytz&#39;
</pre></div>
<p>I can use <code>pip</code> to install the <code>pytz</code> module into my virtual&nbsp;environment.</p>
<div class="highlight"><pre>(myproject)$ pip3 install pytz
</pre></div>
<p>Once it&#8217;s installed, I can verify it&#8217;s working with the same test import&nbsp;command.</p>
<div class="highlight"><pre>(myproject)$ python3 -c &#39;import pytz&#39;
(myproject)$
</pre></div>
<p>When you&#8217;re done with a virtual environment and want to go back to your default system, you use the <code>deactivate</code> command. This restores your environment to the system defaults, including the location of the <code>python3</code> command-line&nbsp;tool.</p>
<div class="highlight"><pre>(myproject)$ deactivate
$ which python3
/usr/local/bin/python3
</pre></div>
<p>If you ever want to work in the <code>myproject</code> environment again, you can just run <code>source bin/activate</code> in the directory like&nbsp;before.</p>
<h3>Reproducing&nbsp;Dependencies</h3>
<p>Once you have a virtual environment, you can continue installing packages with <code>pip</code> as you need them. Eventually, you may want to copy your environment somewhere else. For example, say you want to reproduce your development environment on a production server. Or maybe you want to clone someone else&#8217;s environment on your own machine so you can run their&nbsp;code.</p>
<p><code>pyvenv</code> makes these situations easy. You can use the <code>pip freeze</code> command to save all of your explicit package dependencies into a file. By convention this file is named <code>requirements.txt</code>.</p>
<div class="highlight"><pre>(myproject)$ pip3 freeze &gt; requirements.txt
(myproject)$ cat requirements.txt
numpy==1.8.2
pytz==2014.4
requests==2.3.0
</pre></div>
<p>Now imagine you&#8217;d like to have another virtual environment that matches the <code>myproject</code> environment. You can create a new directory like before using <code>pyvenv</code> and <code>activate</code> it.</p>
<div class="highlight"><pre>$ pyvenv /tmp/otherproject
$ cd /tmp/otherproject
$ source bin/activate
(otherproject)$
</pre></div>
<p>The new environment will have no extra packages&nbsp;installed.</p>
<div class="highlight"><pre>(otherproject)$ pip3 list
pip (1.5.6)
setuptools (2.1)
</pre></div>
<p>You can install all of the packages from the first environment by running <code>pip install</code> on the <code>requirements.txt</code> that you generated with the <code>pip freeze</code> command.</p>
<div class="highlight"><pre>(otherproject)$ pip3 install -r /tmp/myproject/requirements.txt
</pre></div>
<p>This command will crank along for a little while as it retrieves and installs all of the packages required to reproduce the first environment. Once it&#8217;s done, listing the set of installed packages in the second virtual environment will produce the same list of dependencies found in the first virtual&nbsp;environment.</p>
<div class="highlight"><pre>(otherproject)$ pip list
numpy (1.8.2)
pip (1.5.6)
pytz (2014.4)
requests (2.3.0)
setuptools (2.1)
</pre></div>
<p>Using a <code>requirements.txt</code> file is ideal for collaborating with others through a revision control system. You can commit changes to your code at the same time you update your list of package dependencies, ensuring they move in&nbsp;lockstep.</p>
<p>The gotcha with virtual environments is that moving them breaks everything because all of the paths, like <code>python3</code>, are hard-coded to the environment&#8217;s install directory. But that doesn&#8217;t matter. The whole purpose of virtual environments is to make it easy to reproduce the same setup. Instead of moving a virtual environment directory, just <code>freeze</code> the old one, create a new one somewhere else, and reinstall everything from the <code>requirements.txt</code> file.</p>
<h3>Things to&nbsp;Remember</h3>
<ul>
<li>Virtual environments allow you to use <code>pip</code> to install many different versions of the same package on the same machine without&nbsp;conflicts.</li>
<li>Virtual environments are created with <code>pyvenv</code>, enabled with <code>source bin/activate</code>, and disabled with <code>deactivate</code>.</li>
<li>You can dump all of the requirements of an environment with <code>pip freeze</code>. You can reproduce the environment by supplying the <code>requirements.txt</code> file to <code>pip install -r</code>.</li>
<li>In versions of Python before 3.4, the <code>pyvenv</code> tool must be downloaded and installed separately. The command-line tool is called <code>virtualenv</code> instead of <code>pyvenv</code>.</li>
</ul></summary></entry><entry><title>Item 17: Be Defensive When Iterating Over Arguments</title><link href="http://www.effectivepython.com/2015/01/03/be-defensive-when-iterating-over-arguments/" rel="alternate"></link><updated>2014-12-05T23:30:00-08:00</updated><author><name>Brett Slatkin</name></author><id>tag:www.effectivepython.com,2015-01-03:2015/01/03/be-defensive-when-iterating-over-arguments/</id><summary type="html"><p><em>The following is a sample from the new book <a href="/">Effective Python</a>.</em><br><br></p>
<p>When a function takes a list of objects as a parameter, it&#8217;s often important to iterate over that list multiple times. For example, say you want to analyze tourism numbers for the <span class="caps">U.S.</span> State of Texas. Imagine the data set is the number of visitors to each city (in millions per year). You&#8217;d like to figure out what percentage of overall tourism each city&nbsp;receives.</p>
<p>To do this you need a normalization function. It sums the inputs to figure out the total number of tourists per year. Then it divides each city&#8217;s individual visitor count by the total to find that city&#8217;s contribution to the&nbsp;whole.</p>
<div class="highlight"><pre><span class="k">def</span> <span class="nf">normalize</span><span class="p">(</span><span class="n">numbers</span><span class="p">):</span>
<span class="n">total</span> <span class="o">=</span> <span class="nb">sum</span><span class="p">(</span><span class="n">numbers</span><span class="p">)</span>
<span class="n">result</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">numbers</span><span class="p">:</span>
<span class="n">percent</span> <span class="o">=</span> <span class="mi">100</span> <span class="o">*</span> <span class="n">value</span> <span class="o">/</span> <span class="n">total</span>
<span class="n">result</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">percent</span><span class="p">)</span>
<span class="k">return</span> <span class="n">result</span>
</pre></div>
<p>This function works when given a list of&nbsp;visits.</p>
<div class="highlight"><pre><span class="n">visits</span> <span class="o">=</span> <span class="p">[</span><span class="mi">15</span><span class="p">,</span> <span class="mi">35</span><span class="p">,</span> <span class="mi">80</span><span class="p">]</span>
<span class="n">percentages</span> <span class="o">=</span> <span class="n">normalize</span><span class="p">(</span><span class="n">visits</span><span class="p">)</span>
<span class="k">print</span><span class="p">(</span><span class="n">percentages</span><span class="p">)</span>
</pre></div>
<div class="highlight"><pre>&gt;&gt;&gt;
[11.538461538461538, 26.923076923076923, 61.53846153846154]
</pre></div>
<p>To scale this up, I need to read the data from a file that contains every city in all of Texas. I define a generator to do this because then I can reuse the same function later when I want to compute tourism numbers for the whole world, a much larger data&nbsp;set.</p>
<div class="highlight"><pre><span class="k">def</span> <span class="nf">read_visits</span><span class="p">(</span><span class="n">data_path</span><span class="p">):</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">data_path</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
<span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">f</span><span class="p">:</span>
<span class="k">yield</span> <span class="nb">int</span><span class="p">(</span><span class="n">line</span><span class="p">)</span>
</pre></div>
<p>Surprisingly, calling <code>normalize</code> on the generator&#8217;s return value produces no&nbsp;results.</p>
<div class="highlight"><pre><span class="n">it</span> <span class="o">=</span> <span class="n">read_visits</span><span class="p">(</span><span class="s">&#39;/tmp/my_numbers.txt&#39;</span><span class="p">)</span>
<span class="n">percentages</span> <span class="o">=</span> <span class="n">normalize</span><span class="p">(</span><span class="n">it</span><span class="p">)</span>
<span class="k">print</span><span class="p">(</span><span class="n">percentages</span><span class="p">)</span>
</pre></div>
<div class="highlight"><pre>&gt;&gt;&gt;
[]
</pre></div>
<p>The cause of this behavior is that an iterator only produces its results a single time. If you iterate over an iterator or generator that has already raised a <code>StopIteration</code> exception, you won&#8217;t get any results the second time&nbsp;around.</p>
<div class="highlight"><pre><span class="n">it</span> <span class="o">=</span> <span class="n">read_visits</span><span class="p">(</span><span class="s">&#39;/tmp/my_numbers.txt&#39;</span><span class="p">)</span>
<span class="k">print</span><span class="p">(</span><span class="nb">list</span><span class="p">(</span><span class="n">it</span><span class="p">))</span>
<span class="k">print</span><span class="p">(</span><span class="nb">list</span><span class="p">(</span><span class="n">it</span><span class="p">))</span> <span class="c"># Already exhausted</span>
</pre></div>
<div class="highlight"><pre>&gt;&gt;&gt;
[15, 35, 80]
[]
</pre></div>
<p>What&#8217;s confusing is that you also won&#8217;t get any errors when you iterate over an already-exhausted iterator. <code>for</code> loops, the <code>list</code> constructor, and many other functions throughout the Python standard library expect the <code>StopIteration</code> exception to be raised during normal operation. These functions can&#8217;t tell the difference between an iterator that has no output and an iterator that had output and is now&nbsp;exhausted.</p>
<p>To solve this problem, you can explicitly exhaust an input iterator and keep a copy of its entire contents in a list. You can then iterate over the list version of the data as many times as you need to. Here&#8217;s the same function as before, but it defensively copies the input&nbsp;iterator.</p>
<div class="highlight"><pre><span class="k">def</span> <span class="nf">normalize_copy</span><span class="p">(</span><span class="n">numbers</span><span class="p">):</span>
<span class="n">numbers</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">numbers</span><span class="p">)</span> <span class="c"># Copy the iterator</span>
<span class="n">total</span> <span class="o">=</span> <span class="nb">sum</span><span class="p">(</span><span class="n">numbers</span><span class="p">)</span>
<span class="n">result</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">numbers</span><span class="p">:</span>
<span class="n">percent</span> <span class="o">=</span> <span class="mi">100</span> <span class="o">*</span> <span class="n">value</span> <span class="o">/</span> <span class="n">total</span>
<span class="n">result</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">percent</span><span class="p">)</span>
<span class="k">return</span> <span class="n">result</span>
</pre></div>
<p>Now the function works correctly on a generator&#8217;s return&nbsp;value.</p>
<div class="highlight"><pre><span class="n">it</span> <span class="o">=</span> <span class="n">read_visits</span><span class="p">(</span><span class="s">&#39;/tmp/my_numbers.txt&#39;</span><span class="p">)</span>
<span class="n">percentages</span> <span class="o">=</span> <span class="n">normalize_copy</span><span class="p">(</span><span class="n">it</span><span class="p">)</span>
<span class="k">print</span><span class="p">(</span><span class="n">percentages</span><span class="p">)</span>
</pre></div>
<div class="highlight"><pre>&gt;&gt;&gt;
[11.538461538461538, 26.923076923076923, 61.53846153846154]
</pre></div>
<p>The problem with this approach is the copy of the input iterator&#8217;s contents could be large. Copying the iterator could cause your program to run out of memory and crash. One way around this is to accept a function that returns a new iterator each time it&#8217;s&nbsp;called. </p>
<div class="highlight"><pre><span class="k">def</span> <span class="nf">normalize_func</span><span class="p">(</span><span class="n">get_iter</span><span class="p">):</span>
<span class="n">total</span> <span class="o">=</span> <span class="nb">sum</span><span class="p">(</span><span class="n">get_iter</span><span class="p">())</span> <span class="c"># New iterator</span>
<span class="n">result</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">get_iter</span><span class="p">():</span> <span class="c"># New iterator</span>
<span class="n">percent</span> <span class="o">=</span> <span class="mi">100</span> <span class="o">*</span> <span class="n">value</span> <span class="o">/</span> <span class="n">total</span>
<span class="n">result</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">percent</span><span class="p">)</span>
<span class="k">return</span> <span class="n">result</span>
</pre></div>
<p>To use <code>normalize_func</code>, you can pass in a <code>lambda</code> expression that calls the generator and produces a new iterator each&nbsp;time.</p>
<div class="highlight"><pre><span class="n">percentages</span> <span class="o">=</span> <span class="n">normalize_func</span><span class="p">(</span><span class="k">lambda</span><span class="p">:</span> <span class="n">read_visits</span><span class="p">(</span><span class="n">path</span><span class="p">))</span>
</pre></div>
<p>Though it works, having to pass a lambda function like this is clumsy. The better way to achieve the same result is to provide a new container class that implements the <em>iterator protocol</em>.</p>
<p>The iterator protocol is how Python <code>for</code> loops and related expressions traverse the contents of a container type. When Python sees a statement like <code>for x in foo</code> it will actually call <code>iter(foo)</code>. The <code>iter</code> built-in function calls the <code>foo.__iter__</code> special method in turn. The <code>__iter__</code> method must return an iterator object (which itself implements the <code>__next__</code> special method). Then the <code>for</code> loop repeatedly calls the <code>next</code> built-in function on the iterator object until it&#8217;s exhausted (and raises a <code>StopIteration</code> exception).</p>
<p>It sounds complicated, but practically speaking you can achieve all of this behavior for your classes by implementing the <code>__iter__</code> method as a generator. Here I define an iterable container class that reads the files containing tourism&nbsp;data.</p>
<div class="highlight"><pre><span class="k">class</span> <span class="nc">ReadVisits</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data_path</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">data_path</span> <span class="o">=</span> <span class="n">data_path</span>
<span class="k">def</span> <span class="nf">__iter__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">data_path</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
<span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">f</span><span class="p">:</span>
<span class="k">yield</span> <span class="nb">int</span><span class="p">(</span><span class="n">line</span><span class="p">)</span>
</pre></div>
<p>This new container type works correctly when passed to the original function without any&nbsp;modifications.</p>
<div class="highlight"><pre><span class="n">visits</span> <span class="o">=</span> <span class="n">ReadVisits</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
<span class="n">percentages</span> <span class="o">=</span> <span class="n">normalize</span><span class="p">(</span><span class="n">visits</span><span class="p">)</span>
<span class="k">print</span><span class="p">(</span><span class="n">percentages</span><span class="p">)</span>
</pre></div>
<div class="highlight"><pre>&gt;&gt;&gt;
[11.538461538461538, 26.923076923076923, 61.53846153846154]
</pre></div>
<p>This works because the <code>sum</code> method in <code>normalize</code> will call <code>ReadVisits.__iter__</code> to allocate a new iterator object. The <code>for</code> loop to normalize the numbers will also call <code>__iter__</code> to allocate a second iterator object. Each of those iterators will be advanced and exhausted independently, ensuring that each unique iteration sees all of the input data values. The only downside of this approach is it reads the input data multiple&nbsp;times.</p>
<p>Now that you know how containers like <code>ReadVisits</code> work, you can write your functions to ensure that parameters aren&#8217;t just iterators. The protocol states that when an iterator is passed to the <code>iter</code> built-in function, <code>iter</code> will return the iterator itself. In contrast, when a container type is passed to <code>iter</code>, a new iterator object will be returned each time. Thus, you can test an input value for this behavior and raise a <code>TypeError</code> to reject&nbsp;iterators.</p>
<div class="highlight"><pre><span class="k">def</span> <span class="nf">normalize_defensive</span><span class="p">(</span><span class="n">numbers</span><span class="p">):</span>
<span class="k">if</span> <span class="nb">iter</span><span class="p">(</span><span class="n">numbers</span><span class="p">)</span> <span class="ow">is</span> <span class="nb">iter</span><span class="p">(</span><span class="n">numbers</span><span class="p">):</span> <span class="c"># An iterator -- bad!</span>
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s">&#39;Must supply a container&#39;</span><span class="p">)</span>
<span class="n">total</span> <span class="o">=</span> <span class="nb">sum</span><span class="p">(</span><span class="n">numbers</span><span class="p">)</span>
<span class="n">result</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">numbers</span><span class="p">:</span>
<span class="n">percent</span> <span class="o">=</span> <span class="mi">100</span> <span class="o">*</span> <span class="n">value</span> <span class="o">/</span> <span class="n">total</span>
<span class="n">result</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">percent</span><span class="p">)</span>
<span class="k">return</span> <span class="n">result</span>
</pre></div>
<p>This is ideal if you you don&#8217;t want to copy the full input iterator like <code>normalize_copy</code> above, but you also need to iterate over the input data multiple times. This function works as expected for <code>list</code> and <code>ReadVisits</code> inputs because they are containers. It will work for any type of container that follows the iterator&nbsp;protocol.</p>
<div class="highlight"><pre><span class="n">visits</span> <span class="o">=</span> <span class="p">[</span><span class="mi">15</span><span class="p">,</span> <span class="mi">35</span><span class="p">,</span> <span class="mi">80</span><span class="p">]</span>
<span class="n">normalize_defensive</span><span class="p">(</span><span class="n">visits</span><span class="p">)</span> <span class="c"># No error</span>
<span class="n">visits</span> <span class="o">=</span> <span class="n">ReadVisits</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
<span class="n">normalize_defensive</span><span class="p">(</span><span class="n">visits</span><span class="p">)</span> <span class="c"># No error</span>
</pre></div>
<p>The function will raise an exception if the input is iterable but not a&nbsp;container.</p>
<div class="highlight"><pre><span class="n">it</span> <span class="o">=</span> <span class="nb">iter</span><span class="p">(</span><span class="n">visits</span><span class="p">)</span>
<span class="n">normalize_defensive</span><span class="p">(</span><span class="n">it</span><span class="p">)</span>
</pre></div>
<div class="highlight"><pre>&gt;&gt;&gt;
TypeError: Must supply a container
</pre></div>
<h3>Things to&nbsp;Remember</h3>
<ul>
<li>Beware of functions that iterate over input arguments multiple times. If these arguments are iterators you may see strange behavior and missing&nbsp;values.</li>
<li>Python&#8217;s iterator protocol defines how containers and iterators interact with the <code>iter</code> and <code>next</code> built-in functions, <code>for</code> loops, and related&nbsp;expressions.</li>
<li>You can easily define your own iterable container type by implementing the <code>__iter__</code> method as a&nbsp;generator.</li>
<li>You can detect that a value is an iterator (instead of a container) if calling <code>iter</code> on it twice produces the same result, which can then be progress with the <code>next</code> built-in&nbsp;function.</li>
</ul></summary></entry><entry><title>The Rough Cut Is Online</title><link href="http://www.effectivepython.com/2014/12/18/rough-cut-is-online/" rel="alternate"></link><updated>2014-12-18T19:15:00-08:00</updated><author><name>Brett Slatkin</name></author><id>tag:www.effectivepython.com,2014-12-18:2014/12/18/rough-cut-is-online/</id><summary type="html"><p>Can&#8217;t wait until next year for the book to be published? The rough cut is now <a href="http://safari.informit.com/9780134034416">available on Safari Books Online</a>. This is an early preview of the full content of the book before editing has been&nbsp;completed.</p></summary></entry><entry><title>Now Available for Preorder</title><link href="http://www.effectivepython.com/2014/12/04/preorder-the-book/" rel="alternate"></link><updated>2014-12-04T23:45:00-08:00</updated><author><name>Brett Slatkin</name></author><id>tag:www.effectivepython.com,2014-12-04:2014/12/04/preorder-the-book/</id><summary type="html"><p><em>Effective Python</em> is now available for preorder on Amazon. <a href="http://amzn.to/1ylkKmc">Follow this link to buy your copy in advance</a>. It will ship in early 2015 once the book is&nbsp;published.</p></summary></entry><entry><title>Final Draft Done</title><link href="http://www.effectivepython.com/2014/11/16/final-draft-done/" rel="alternate"></link><updated>2014-11-16T00:30:00-08:00</updated><author><name>Brett Slatkin</name></author><id>tag:www.effectivepython.com,2014-11-16:2014/11/16/final-draft-done/</id><summary type="html"><p>The final draft of the book is done. It&#8217;s 55,000 words, 250+ pages, 8 chapters, 59 items. Reviewers spent a lot of time looking over earlier drafts to ensure that the book will be useful. Now it&#8217;s off to production to be turned into a printable&nbsp;layout.</p></summary></entry><entry><title>Welcome</title><link href="http://www.effectivepython.com/2014/08/18/welcome-to-effective-python/" rel="alternate"></link><updated>2014-08-18T09:45:00-07:00</updated><author><name>Brett Slatkin</name></author><id>tag:www.effectivepython.com,2014-08-18:2014/08/18/welcome-to-effective-python/</id><summary type="html"><p>This website is now live! Here you&#8217;ll find updates about my progress towards <em>Effective Python</em>&#8216;s eventual publishing by Addison-Wesley. You can find other books from the <em>Effective</em> series <a href="http://www.informit.com/imprint/series_detail.aspx?st=61267">in Pearson&#8217;s online store</a>.</p></summary></entry></feed>