-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathconvertire-codice-verso-python-3-con-2to3.html
1347 lines (1154 loc) · 77.2 KB
/
convertire-codice-verso-python-3-con-2to3.html
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
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html>
<meta charset=utf-8>
<title>Convertire codice verso Python 3 con 2to3 - Immersione in Python 3</title>
<!--[if IE]><script src=j/html5.js></script><![endif]-->
<link rel=stylesheet href=dip3.css>
<style>
h1:before{counter-increment:h1;content:'Appendice A. '}
h2:before{counter-increment:h2;content:'A.' counter(h2) '. '}
h3:before{counter-increment:h3;content:'A.' counter(h2) '.' counter(h3) '. '}
</style>
<link rel=stylesheet media='only screen and (max-device-width: 480px)' href=mobile.css>
<link rel=stylesheet media=print href=print.css>
<meta content='initial-scale=1.0' name=viewport>
<form action=http://www.google.com/cse><div><input type=hidden name=cx value=014021643941856155761:l5eihuescdw><input name=ie type=hidden value=UTF-8> <input type=search name=q size=25 placeholder="powered by Google™"> <input name=sa type=submit value=Search></div></form>
<p>Voi siete qui: <a href=index.html>Inizio</a> <span class=u>‣</span> <a href=indice.html#convertire-codice-verso-python-3-con-2to3>Immersione in Python 3</a> <span class=u>‣</span>
<p id=level>Livello di difficoltà: <span class=u title=professionale>♦♦♦♦♦</span>
<h1>Convertire codice verso Python 3 con <code>2to3</code></h1>
<blockquote class=q>
<p><span class=u>❝</span> La vita è piacevole. La morte è pacifica. È la transizione che crea dei problemi. <span class=u>❞</span><br>— Isaac Asimov (attribuita)
</blockquote>
<p id=toc>
<h2 id=divingin>Immersione!</h2>
<p class=f>Una quantità talmente grande di caratteristiche del linguaggio è cambiata tra Python 2 e Python 3 che solo un numero molto ridotto e sempre più esiguo di programmi verrà eseguito senza modifiche da entrambi gli interpreti. Per facilitare questa transizione, Python 3 include uno script di utilità chiamato <code>2to3</code>, che prende in ingresso il vostro codice sorgente in Python 2 e lo converte automaticamente verso Python 3 tanto quanto gli è possibile. Il <a href=caso-di-studio-convertire-chardet-verso-python-3.html#running2to3>Caso di studio: convertire <code>chardet</code> verso Python 3</a> descrive come eseguire <code>2to3</code>, poi mostra alcune cose che lo script non riesce a correggere automaticamente. Questa appendice illustra ciò che lo script <em>riesce</em> a correggere automaticamente
<h2 id=print>L’istruzione <code>print</code></h2>
<p>In Python 2 <code><dfn>print</dfn></code> era un’istruzione. Per stampare una cosa qualsiasi bastava farla seguire alla parola chiave <code>print</code>. In Python 3 <a href=il-vostro-primo-programma-python.html#divingin><code>print()</code> è una funzione</a>. Qualunque cosa vogliate stampare, passatela a <code>print()</code> nel modo in cui la passate a qualsiasi altra funzione.
<table>
<tr><th>Note
<th>Python 2
<th>Python 3
<tr><th>①
<td><code class=pp>print</code>
<td><code class=pp>print()</code>
<tr><th>②
<td><code class=pp>print 1</code>
<td><code class=pp>print(1)</code>
<tr><th>③
<td><code class=pp>print 1, 2</code>
<td><code class=pp>print(1, 2)</code>
<tr><th>④
<td><code class=pp>print 1, 2,</code>
<td><code class=pp>print(1, 2, end=' ')</code>
<tr><th>⑤
<td><code class=pp>print >>sys.stderr, 1, 2, 3</code>
<td><code class=pp>print(1, 2, 3, file=sys.stderr)</code>
</table>
<ol>
<li>Per stampare una riga vuota, invocate <code>print()</code> senza alcun argomento.
<li>Per stampare un singolo valore, invocate <code>print()</code> con un argomento.
<li>Per stampare due valori separati da uno spazio, invocate <code>print()</code> con due argomenti.
<li>Questo può risultare ingannevole. In Python 2 un’istruzione <code>print</code> conclusa da una virgola avrebbe stampato i valori separati da spazi, seguiti da uno spazio finale, evitando di stampare un ritorno a capo. (Tecnicamente, il funzionamento di <code>print</code> è più complicato. In Python 2 l’istruzione <code>print</code> usava un attributo chiamato <var>softspace</var>, ora deprecato. Invece di stampare uno spazio, Python 2 impostava <code>sys.stdout.softspace</code> a <code>1</code>, rimandando la stampa di quel carattere fino a quando non veniva stampato qualcos’altro sulla stessa riga. Se la successiva istruzione <code>print</code> stampava un ritorno a capo, <code>sys.stdout.softspace</code> veniva impostato a <code>0</code> e lo spazio non sarebbe comparso. Probabilmente non avreste mai notato la differenza a meno che la vostra applicazione non fosse stata sensibile alla presenza o all’assenza di spazi bianchi alla fine di una riga nel testo generato da <code>print</code>.) Per ottenere questo comportamento in Python 3 è necessario passare <code>end=' '</code> come argomento con nome alla funzione <code>print()</code>. L’argomento <code>end</code> assume <code>'\n'</code> (un ritorno a capo) come valore predefinito, quindi va modificato per sopprimere il ritorno a capo dopo la stampa degli altri argomenti.
<li>In Python 2 potevate redirigere l’uscita verso un canale — come <code>sys.stderr</code> — utilizzando la sintassi <code>>>nome_del_canale</code>. Per ottenere la redirezione in Python 3 è necessario passare il canale come valore dell’argomento con nome <code>file</code>. L’argomento <code>file</code> assume <code>sys.stdout</code> (uscita standard) come valore predefinito, quindi va modificato per produrre l’uscita su un canale differente.
</ol>
<h2 id=unicodeliteral>Letterali stringa Unicode</h2>
<p>Python 2 aveva due tipi di stringa: stringhe <dfn>Unicode</dfn> e stringhe non Unicode. Python 3 ha un solo tipo di stringa: <a href=stringhe.html#divingin>stringhe Unicode</a>.
<table>
<tr><th>Note
<th>Python 2
<th>Python 3
<tr><th>①
<td><code class=pp>u'PapayaWhip'</code>
<td><code class=pp>'PapayaWhip'</code>
<tr><th>②
<td><code class=pp>ur'PapayaWhip\foo'</code>
<td><code class=pp>r'PapayaWhip\foo'</code>
</table>
<ol>
<li>I letterali stringa Unicode sono semplicemente convertiti in letterali stringa, che in Python 3 sono sempre di tipo Unicode.
<li>Le <i>stringhe raw</i> Unicode (per le quali Python non effettua l’escape automatico dei backslash) vengono convertite in stringhe raw. In Python 3, le stringhe raw sono sempre di tipo Unicode.
</ol>
<h2 id=unicode>La funzione globale <code>unicode()</code></h2>
<p>Python 2 aveva due funzioni globali per convertire oggetti in stringhe: <code>unicode()</code> per convertirli in stringhe Unicode e <code>str()</code> per convertirli in stringhe non Unicode. Python 3 ha un solo tipo di stringhe, <a href=stringhe.html#divingin>stringhe Unicode</a>, quindi la funzione <code>str()</code> è tutto quello che vi serve. (La funzione <code>unicode()</code> non esiste più.)
<table>
<tr><th>Note
<th>Python 2
<th>Python 3
<tr><th>
<td><code class=pp>unicode(anything)</code>
<td><code class=pp>str(anything)</code>
</table>
<h2 id=long>Il tipo di dato <code>long</code></h2>
<p>Python 2 aveva tipi <code>int</code> e <code><dfn>long</dfn></code> separati per i numeri non in virgola mobile. Un <code>int</code> non poteva essere più grande di <a href=#renames><code>sys.maxint</code></a>, il cui valore variava a seconda della piattaforma. I <code>long</code> venivano definiti aggiungendo una <code>L</code> alla fine del numero e potevano essere, be’, più lunghi degli <code>int</code>. In Python 3 <a href=tipi-di-dato-nativi.html#numbers>c’è solo un tipo di numeri interi</a> chiamato <code>int</code>, che si comporta quasi sempre come il tipo <code>long</code> in Python 2. Dato che non ci sono più due tipi, non c’è alcun bisogno di una sintassi speciale per distinguerli.
<p>Per approfondire l’argomento, si consiglia la lettura della <a href=http://www.python.org/dev/peps/pep-0237/><abbr>PEP</abbr> 237: Unificare gli interi lunghi e gli interi</a>.
<table>
<tr><th>Note
<th>Python 2
<th>Python 3
<tr><th>①
<td><code class=pp>x = 1000000000000L</code>
<td><code class=pp>x = 1000000000000</code>
<tr><th>②
<td><code class=pp>x = 0xFFFFFFFFFFFFL</code>
<td><code class=pp>x = 0xFFFFFFFFFFFF</code>
<tr><th>③
<td><code class=pp>long(x)</code>
<td><code class=pp>int(x)</code>
<tr><th>④
<td><code class=pp>type(x) is long</code>
<td><code class=pp>type(x) is int</code>
<tr><th>⑤
<td><code class=pp>isinstance(x, long)</code>
<td><code class=pp>isinstance(x, int)</code>
</table>
<ol>
<li>I letterali <code>long</code> in base 10 diventano letterali <code>int</code> in base 10.
<li>I letterali <code>long</code> in base 16 diventano letterali <code>int</code> in base 16.
<li>In Python 3 la vecchia funzione <code>long()</code> non esiste più, dato che i <code>long</code> non esistono più. Per convertire una variabile in un intero, usate la funzione <code>int()</code>.
<li>Per controllare se una variabile è un intero, recuperatene il tipo e confrontatelo con <code>int</code>, non con <code>long</code>.
<li>Potete anche usare la funzione <code>isinstance()</code> per controllare i tipi di dato; usate ancora <code>int</code>, non <code>long</code>, per controllare gli interi.
</ol>
<h2 id=ne>Il confronto di disuguaglianza con <></h2>
<p>Python 2 supportava <code><></code> come sinonimo di <code>!=</code>, l’operatore per il confronto di disuguaglianza. Python 3 supporta l’operatore <code>!=</code>, ma non <code><></code>.
<table>
<tr><th>Note
<th>Python 2
<th>Python 3
<tr><th>①
<td><code class=pp>if x <> y:</code>
<td><code class=pp>if x != y:</code>
<tr><th>②
<td><code class=pp>if x <> y <> z:</code>
<td><code class=pp>if x != y != z:</code>
</table>
<ol>
<li>Un semplice confronto.
<li>Un confronto più complesso tra tre valori.
</ol>
<h2 id=has_key>Il metodo <code>has_key()</code> per i dizionari</h2>
<p>In Python 2 i dizionari avevano un metodo <code><dfn>has_key</dfn>()</code> per verificare che il dizionario contenesse una certa chiave. In Python 3 questo metodo non esiste più. Al suo posto dovete usare <a href=tipi-di-dato-nativi.html#mixed-value-dictionaries>l’operatore <code>in</code></a>.
<table>
<tr><th>Note
<th>Python 2
<th>Python 3
<tr><th>①
<td><code class=pp>a_dictionary.has_key('PapayaWhip')</code>
<td><code class=pp>'PapayaWhip' in a_dictionary</code>
<tr><th>②</th >
<td><code class=pp>a_dictionary.has_key(x) or a_dictionary.has_key(y)</code>
<td><code class=pp>x in a_dictionary or y in a_dictionary</code>
<tr><th>③
<td><code class=pp>a_dictionary.has_key(x or y)</code>
<td><code class=pp>(x or y) in a_dictionary</code>
<tr><th>④
<td><code class=pp>a_dictionary.has_key(x + y)</code>
<td><code class=pp>(x + y) in a_dictionary</code>
<tr><th>⑤
<td><code class=pp>x + a_dictionary.has_key(y)</code>
<td><code class=pp>x + (y in a_dictionary)</code>
</table>
<ol>
<li>La forma più semplice.
<li>L’operatore <code>in</code> ha la precedenza sull’operatore <code>or</code>, quindi in questo caso non c’è alcun bisogno di usare le parentesi attorno a <code>x in a_dictionary</code> o a <code>y in a_dictionary</code>.
<li>D’altra parte, in questo caso <em>avete</em> bisogno di usare le parentesi attorno a <code>x or y</code>, per lo stesso motivo — <code>in</code> ha la precedenza su <code>or</code>. Notate che questo codice è completamente differente da quello nella riga precedente. Python interpreta prima <code>x or y</code>, che dà come risultato <var>x</var> (se <var>x</var> è <a href=tipi-di-dato-nativi.html#booleans>vero in un contesto logico</a>) o <var>y</var>; poi prende quel singolo valore e controlla se è una chiave di <var>a_dictionary</var>.
<li>L’operatore <code>+</code> ha la precedenza sull’operatore <code>in</code>, quindi questa forma non avrebbe tecnicamente bisogno delle parentesi attorno a <code>x + y</code>, ma <code>2to3</code> le aggiunge comunque.
<li>Questa forma ha certamente bisogno delle parentesi attorno a <code>y in a_dictionary</code>, dato che l’operatore <code>+</code> ha la precedenza sull’operatore <code>in</code>.
</ol>
<h2 id=dict>Metodi dei dizionari che restituiscono liste</h2>
<p>In Python 2 molti metodi dei dizionari restituivano liste. I metodi più frequentemente usati erano <code><dfn>keys</dfn>()</code>, <code><dfn>items</dfn>()</code> e <code><dfn>values</dfn>()</code>. In Python 3 tutti questi metodi restituiscono <dfn>viste</dfn> dinamiche. In alcuni contesti questo non è un problema. Se il valore di ritorno del metodo viene immediatamente passato a un’altra funzione che itera attraverso l’intera sequenza, non fa alcuna differenza che il tipo reale di quel valore sia una lista o una vista. In altri contesti ha invece molta importanza. Se vi stavate aspettando una lista completa con elementi accessibili individualmente, il vostro programma si bloccherà perché le viste non supportano l’accesso basato su indici.
<table>
<tr><th>Note
<th>Python 2
<th>Python 3
<tr><th>①
<td><code class=pp>a_dictionary.keys()</code>
<td><code class=pp>list(a_dictionary.keys())</code>
<tr><th>②
<td><code class=pp>a_dictionary.items()</code>
<td><code class=pp>list(a_dictionary.items())</code>
<tr><th>③
<td><code class=pp>a_dictionary.iterkeys()</code>
<td><code class=pp>iter(a_dictionary.keys())</code>
<tr><th>④
<td><code class=pp>[i for i in a_dictionary.iterkeys()]</code>
<td><code class=pp>[i for i in a_dictionary.keys()]</code>
<tr><th>⑤
<td><code class=pp>min(a_dictionary.keys())</code>
<td><i>nessuna modifica</i>
</table>
<ol>
<li><code>2to3</code> pecca per eccesso di prudenza, convertendo il valore di ritorno di <code>keys()</code> in una lista statica tramite la funzione <code>list()</code>. Questo codice funzionerà sempre, ma sarà meno efficiente rispetto all’uso di una vista. Dovreste esaminare il codice convertito per controllare se una lista è assolutamente necessaria o se una vista sarebbe sufficiente.
<li>Un’altra conversione di vista in lista, questa volta con il metodo <code>items()</code>. <code>2to3</code> farà la stessa cosa con il metodo <code>values()</code>.
<li>Python 3 non supporta più il metodo <code>iterkeys()</code>. Usate <code>keys()</code> e, se necessario, convertite la vista in un iteratore tramite la funzione <code>iter()</code>.
<li><code>2to3</code> riconosce quando il metodo <code>iterkeys()</code> viene usato in una descrizione di lista e lo converte nel metodo <code>keys()</code> (senza circondarlo con una chiamata aggiuntiva a <code>iter()</code>). Questa modifica funziona perché le viste sono iterabili.
<li><code>2to3</code> riconosce che il risultato restituito dal metodo <code>keys()</code> viene immediatamente passato a una funzione che itera su un’intera sequenza, così non ha bisogno di convertirne il valore in una lista. La funzione <code>min()</code> itererà tranquillamente attraverso la vista. Queste considerazioni valgono per le funzioni <code>min()</code>, <code>max()</code>, <code>sum()</code>, <code>list()</code>, <code>tuple()</code>, <code>set()</code>, <code>sorted()</code>, <code>any()</code> e <code>all()</code>.
</ol>
<h2 id=imports>Moduli che sono stati rinominati o riorganizzati</h2>
<p>Diversi moduli nella libreria standard di Python sono stati rinominati. Diversi altri moduli in relazione tra loro sono stati combinati o riorganizzati per rendere le loro associazioni più logiche.
<h3 id=http><code>http</code></h3>
<p>In Python 3 molti moduli relativi al protocollo <abbr>HTTP</abbr> sono stati combinati in un unico pacchetto chiamato <code>http</code>.
<table>
<tr><th>Note
<th>Python 2
<th>Python 3
<tr><th>①
<td><code class=pp>import <dfn>httplib</dfn></code>
<td><code class=pp>import http.client</code>
<tr><th>②
<td><code class=pp>import <dfn>Cookie</dfn></code>
<td><code class=pp>import http.cookies</code>
<tr><th>③
<td><code class=pp>import <dfn>cookielib</dfn></code>
<td><code class=pp>import http.cookiejar</code>
<tr><th>④
<td><pre class=pp><code>import <dfn>BaseHTTPServer</dfn>
import <dfn>SimpleHTTPServer</dfn>
import <dfn>CGIHttpServer</dfn></code></pre>
<td><code class=pp>import http.server</code>
</table>
<ol>
<li>Il modulo <code>http.client</code> implementa una libreria di basso livello che può richiedere risorse <abbr>HTTP</abbr> e interpretare le risposte <abbr>HTTP</abbr>.
<li>Il modulo <code>http.cookies</code> fornisce un’interfaccia Python ai cookie inviati a un browser tramite l’intestazione <abbr>HTTP</abbr> <code>Set-Cookie:</code>.
<li>Il modulo <code>http.cookiejar</code> manipola gli effettivi file usati dai browser web più popolari per memorizzare i cookie.
<li>Il modulo <code>http.server</code> fornisce un server <abbr>HTTP</abbr> di base.
</ol>
<h3 id=urllib><code>urllib</code></h3>
<p>Python 2 aveva un macello di moduli sovrapposti per riconoscere, codificare e recuperare gli <abbr>URL</abbr>. In Python 3 tutti questi moduli sono stati riorganizzati e combinati in un singolo pacchetto chiamato <code>urllib</code>.
<table>
<tr><th>Note
<th>Python 2
<th>Python 3
<tr><th>①
<td><code class=pp>import <dfn>urllib</dfn></code>
<td><code class=pp>import urllib.request, urllib.parse, urllib.error</code>
<tr><th>②
<td><code class=pp>import <dfn>urllib2</dfn></code>
<td><code class=pp>import urllib.request, urllib.error</code>
<tr><th>③
<td><code class=pp>import <dfn>urlparse</dfn></code>
<td><code class=pp>import urllib.parse</code>
<tr><th>④
<td><code class=pp>import <dfn>robotparser</dfn></code>
<td><code class=pp>import urllib.robotparser</code>
<tr><th>⑤
<td><pre class=pp><code>from urllib import <dfn>FancyURLopener</dfn>
from urllib import urlencode</code></pre>
<td><pre class=pp><code>from urllib.request import FancyURLopener
from urllib.parse import urlencode</code></pre>
<tr><th>⑥
<td><pre class=pp><code>from urllib2 import <dfn>Request</dfn>
from urllib2 import <dfn>HTTPError</dfn></code></pre>
<td><pre class=pp><code>from urllib.request import Request
from urllib.error import HTTPError</code></pre>
</table>
<ol>
<li>Il vecchio modulo <code>urllib</code> di Python 2 raccoglieva una varietà di funzioni, comprese <code>urlopen()</code> per recuperare dati e <code>splittype()</code>, <code>splithost()</code> e <code>splituser()</code> per suddividere un <abbr>URL</abbr> nelle sue parti costituenti. Queste funzioni sono state riorganizzate più logicamente nell’ambito del nuovo pacchetto <code>urllib</code>. <code>2to3</code> modificherà anche tutte le chiamate a queste funzioni in modo da usare il nuovo schema di nomi.
<li>Il vecchio modulo <code>urllib2</code> di Python 2 è stato incorporato nel pacchetto <code>urllib</code> di Python 3. Tutte le vostre funzionalità di <code>urllib2</code> preferite — il metodo <code>build_opener()</code>, gli oggetti <code>Request</code>, <code>HTTPBasicAuthHandler</code> e compagnia — sono ancora disponibili.
<li>Il modulo <code>urllib.parse</code> di Python 3 contiene tutte le funzioni di riconoscimento del vecchio modulo <code>urlparse</code> di Python 2.
<li>Il modulo <code>urllib.robotparser</code> riconosce <a href=http://www.robotstxt.org/>i file <code>robots.txt</code></a>.
<li>La classe <code>FancyURLopener</code> che gestisce le redirezioni <abbr>HTTP</abbr> e altri codici di stato è ancora disponibile nel nuovo modulo <code>urllib.request</code>. La funzione <code>urlencode()</code> è stata spostata in <code>urllib.parse</code>.
<li>L’oggetto <code>Request</code> è ancora disponibile in <code>urllib.request</code>, ma costanti come <code>HTTPError</code> sono state spostate in <code>urllib.error</code>.
</ol>
<p>Vi ho detto che <code>2to3</code> riscriverà anche le vostre chiamate di funzione? Per esempio, se il vostro codice in Python 2 importa il modulo <code>urllib</code> e invoca <code>urllib.urlopen()</code> per prelevare dati, <code>2to3</code> correggerà sia l’istruzione di importazione che la chiamata di funzione.
<table>
<tr><th>Note
<th>Python 2
<th>Python 3
<tr><th>
<td><pre class=pp><code>import urllib
print urllib.urlopen('http://diveintopython3.org/').read()</code></pre>
<td><pre class=pp><code>import urllib.request, urllib.parse, urllib.error
print(urllib.request.urlopen('http://diveintopython3.org/').read())</code></pre>
</table>
<h3 id=dbm><code>dbm</code></h3>
<p>Tutti i vari cloni di <abbr>DBM</abbr> si trovano ora in un singolo pacchetto chiamato <code>dbm</code>. Se avete bisogno di una specifica variante come <abbr>GNU</abbr> <abbr>DBM</abbr> potete importare il modulo appropriato nell’ambito del pacchetto <code>dbm</code>.
<table>
<tr><th>Note
<th>Python 2
<th>Python 3
<tr><th>
<td><code class=pp>import <dfn>dbm</dfn></code>
<td><code class=pp>import dbm.ndbm</code>
<tr><th>
<td><code class=pp>import <dfn>gdbm</dfn></code>
<td><code class=pp>import dbm.gnu</code>
<tr><th>
<td><code class=pp>import <dfn>dbhash</dfn></code>
<td><code class=pp>import dbm.bsd</code>
<tr><th>
<td><code class=pp>import <dfn>dumbdbm</dfn></code>
<td><code class=pp>import dbm.dumb</code>
<tr><th>
<td><pre class=pp><code>import <dfn>anydbm</dfn>
import whichdb</code></pre>
<td><code class=pp>import dbm</code>
</table>
<h3 id=xmlrpc><code>xmlrpc</code></h3>
<p><abbr>XML-RPC</abbr> è un metodo leggero per eseguire chiamate <abbr>RPC</abbr> remote su <abbr>HTTP</abbr>. La libreria client di <abbr>XML-RPC</abbr> e diverse implementazioni server di <abbr>XML-RPC</abbr> sono ora combinate in un singolo pacchetto chiamato <code>xmlrpc</code>.
<table>
<tr><th>Note
<th>Python 2
<th>Python 3
<tr><th>
<td><code class=pp>import <dfn>xmlrpclib</dfn></code>
<td><code class=pp>import xmlrpc.client</code>
<tr><th>
<td><pre class=pp><code>import <dfn>DocXMLRPCServer</dfn>
import <dfn>SimpleXMLRPCServer</dfn></code></pre>
<td><code class=pp>import xmlrpc.server</code>
</table>
<h3 id=othermodules>Altri moduli</h3>
<table>
<tr><th>Note
<th>Python 2
<th>Python 3
<tr><th>①
<td><pre class=pp><code>try:
import <dfn>cStringIO</dfn> as <dfn>StringIO</dfn>
except ImportError:
import StringIO</code></pre>
<td><code class=pp>import io</code>
<tr><th>②
<td><pre class=pp><code>try:
import cPickle as pickle
except ImportError:
import pickle</code></pre>
<td><code class=pp>import pickle</code>
<tr><th>③
<td><code class=pp>import <dfn>__builtin__</dfn></code>
<td><code class=pp>import builtins</code>
<tr><th>④
<td><code class=pp>import <dfn>copy_reg</dfn></code>
<td><code class=pp>import copyreg</code>
<tr><th>⑤
<td><code class=pp>import <dfn>Queue</dfn></code>
<td><code class=pp>import queue</code>
<tr><th>⑥
<td><code class=pp>import <dfn>SocketServer</dfn></code>
<td><code class=pp>import socketserver</code>
<tr><th>⑦
<td><code class=pp>import <dfn>ConfigParser</dfn></code>
<td><code class=pp>import configparser</code>
<tr><th>⑧
<td><code class=pp>import repr</code>
<td><code class=pp>import reprlib</code>
<tr><th>⑨
<td><code class=pp>import <dfn>commands</dfn></code>
<td><code class=pp>import subprocess</code>
</table>
<ol>
<li>Un idioma comune in Python 2 era quello di importare <code>cStringIO as StringIO</code> e, in caso di errore, importare <code>StringIO</code> al suo posto. Non è necessario farlo in Python 3, poiché il modulo <code>io</code> lo farà per voi: troverà l’implementazione più veloce disponibile e la utilizzerà automaticamente.
<li>Un idioma simile veniva usato per importare l’implementazione più veloce di pickle, il protocollo di serializzazione degli oggetti. Non è necessario usare tale idioma in Python 3, poiché il modulo <code>pickle</code> lo farà per voi.
<li>Il modulo <code>builtins</code> contiene le funzioni globali, le classi e le costanti usate in tutto il linguaggio Python. Ridefinire una funzione nel modulo <code>builtins</code> ridefinirà la funzione globale ovunque. Questo è esattamente tanto potente e spaventoso quanto sembra.
<li>Il modulo <code>copyreg</code> aggiunge il supporto per la serializzazione ai vostri tipi di dato definiti in C.
<li>Il modulo <code>queue</code> implementa una coda che supporta molteplici produttori e consumatori.
<li>Il modulo <code>socketserver</code> fornisce classi base generiche per implementare differenti tipi di server per le socket.
<li>Il modulo <code>configparser</code> riconosce i file di configurazione sullo stile dei file <abbr>INI</abbr>.
<li>Il modulo <code>reprlib</code> reimplementa la funzione built-in <code>repr()</code> introducendo controlli aggiuntivi su quanto possono essere lunghe le rappresentazioni prima di venire troncate.
<li>Il modulo <code>subprocess</code> vi permette di creare processi, connettervi ai loro canali e ottenere i loro codici di ritorno.
</ol>
<h2 id=import>Importazioni relative all’interno di un pacchetto</h2>
<p>Un pacchetto è un gruppo di moduli correlati che funziona come una singola entità. In Python 2, quando i moduli all’interno di un pacchetto devono fare riferimento gli uni agli altri, si usa l’idioma <code>import foo</code> oppure <code>from foo import Bar</code>. L’interprete Python 2 prima cerca all’interno del pacchetto corrente per trovare <code>foo.py</code>, poi si sposta nelle altre directory contenute nel percorso di ricerca di Python (<code>sys.path</code>). Python 3 funziona in modo leggermente diverso. Invece di cercare nel pacchetto corrente, si sposta direttamente sul percorso di ricerca di Python. Se volete che un modulo in un pacchetto importi un altro modulo nello stesso pacchetto, dovete esplicitamente fornire il percorso relativo tra i due moduli.
<p>Supponete di avere questo pacchetto, contenente più file nella stessa directory:
<pre>chardet/
|
+--__init__.py
|
+--constants.py
|
+--mbcharsetprober.py
|
+--universaldetector.py</pre>
<p>Ora supponete che <code>universaldetector.py</code> abbia bisogno di importare l’intero file <code>constants.py</code> e una classe da <code>mbcharsetprober.py</code>. Come fareste?
<table>
<tr><th>Note
<th>Python 2
<th>Python 3
<tr><th>①
<td><code class=pp>import constants</code>
<td><code class=pp>from . import constants</code>
<tr><th>②
<td><code class=pp>from mbcharsetprober import MultiByteCharSetProber</code>
<td><code class=pp>from .mbcharsetprober import MultiByteCharsetProber</code>
</table>
<ol>
<li>Quando dovete importare un intero modulo in qualche punto del vostro pacchetto, usate la nuova sintassi <code>from . import</code>. Il punto è in realtà il percorso relativo da questo file (<code>universaldetector.py</code>) al file che volete importare (<code>constants.py</code>). In questo caso sono nella stessa directory, quindi è sufficiente un singolo punto. Potete anche importare dalla directory superiore (<code>from .. import altromodulo</code>) o da una sottodirectory.
<li>Per importare una specifica classe o funzione da un altro modulo direttamente nello spazio di nomi del vostro modulo, fate precedere al nome del modulo obiettivo un prefisso contenente un percorso relativo meno lo slash finale. In questo caso <code>mbcharsetprober.py</code> è nella stessa directory di <code>universaldetector.py</code>, quindi il percorso è un singolo punto. Potete anche importare dalla directory genitore (<code>from ..altromodulo import AltraClasse</code>) o da una sottodirectory.
</ol>
<h2 id=next>Il metodo <code>next()</code> degli iteratori</h2>
<p>In Python 2 gli iteratori hanno un metodo <code><dfn>next</dfn>()</code> che restituisce l’elemento successivo nella sequenza. Questo è ancora vero in Python 3, ma esiste anche <a href=generatori.html#generators>una funzione globale <code>next()</code></a> che prende un iteratore come argomento.
<table>
<tr><th>Note
<th>Python 2
<th>Python 3
<tr><th>①
<td><code class=pp>anIterator.next()</code>
<td><code class=pp>next(anIterator)</code>
<tr><th>②
<td><code class=pp>a_function_that_returns_an_iterator().next()</code>
<td><code class=pp>next(a_function_that_returns_an_iterator())</code>
<tr><th>③
<td><pre class=pp><code>class A:
def next(self):
pass</code></pre>
<td><pre class=pp><code>class A:
def __next__(self):
pass</code></pre>
<tr><th>④
<td><pre class=pp><code>class A:
def next(self, x, y):
pass</code></pre>
<td><i>nessuna modifica</i>
<tr><th>⑤
<td><pre class=pp><code>next = 42
for an_iterator in a_sequence_of_iterators:
an_iterator.next()</code></pre>
<td><pre class=pp><code>next = 42
for an_iterator in a_sequence_of_iterators:
an_iterator.__next__()</code></pre>
</table>
<ol>
<li>Nel caso più semplice, invece di chiamare il metodo <code>next()</code> di un iteratore ora passate l’iteratore stesso alla funzione globale <code>next()</code>.
<li>Se avete una funzione che restituisce un iteratore, chiamate la funzione e passate il risultato alla funzione <code>next()</code>. (Lo script <code>2to3</code> è abbastanza intelligente da convertire questi casi in maniera appropriata.)
<li>Se definite una vostra classe e volete usarla come un iteratore, definite il metodo speciale <code>__next__()</code>.
<li>Se definite una vostra classe e la dotate di un metodo chiamato <code>next()</code> che prende uno o più argomenti, <code>2to3</code> non lo toccherà. Questa classe non può essere usata come un iteratore, perché il suo metodo <code>next()</code> accetta un certo numero di argomenti.
<li>Questo caso è un po’ complicato. Se avete una variabile locale chiamata <var>next</var>, allora essa ha precedenza sulla funzione globale <code>next()</code>. Perciò, siete obbligati a chiamare il metodo speciale <code>__next__()</code> dell’iteratore per ottenere l’elemento successivo nella sequenza. (In alternativa potreste anche modificare il codice in modo che la variabile locale non sia più chiamata <var>next</var>, ma <code>2to3</code> non lo farà automaticamente per voi.)
</ol>
<h2 id=filter>La funzione globale <code>filter()</code></h2>
<p>In Python 2 la funzione <code><dfn>filter</dfn>()</code> restituiva una lista come risultato del filtraggio di una sequenza attraverso una funzione che restituisce <code>True</code> o <code>False</code> per ogni elemento della sequenza. In Python 3 la funzione <code>filter()</code> restituisce un iteratore, non una lista.
<table>
<tr><th>Note
<th>Python 2
<th>Python 3
<tr><th>①
<td><code class=pp>filter(a_function, a_sequence)</code>
<td><code class=pp>list(filter(a_function, a_sequence))</code>
<tr><th>②
<td><code class=pp>list(filter(a_function, a_sequence))</code>
<td><i>nessuna modifica</i>
<tr><th>③
<td><code class=pp>filter(None, a_sequence)</code>
<td><code class=pp>[i for i in a_sequence if i]</code>
<tr><th>④
<td><code class=pp>for i in filter(None, a_sequence):</code>
<td><i>nessuna modifica</i>
<tr><th>⑤
<td><code class=pp>[i for i in filter(a_function, a_sequence)]</code>
<td><i>nessuna modifica</i>
</table>
<ol>
<li>Nel caso più basilare, <code>2to3</code> circonderà la chiamata a <code>filter()</code> con una chiamata a <code>list()</code>, che semplicemente itera attraverso il suo argomento e restituisce una vera lista.
<li>Comunque, se la chiamata a <code>filter()</code> è <em>già</em> circondata da <code>list()</code> allora <code>2to3</code> non farà nulla, in quanto è irrilevante che <code>filter()</code> restituisca un iteratore.
<li>Per la sintassi speciale di <code>filter(None, ...)</code>, <code>2to3</code> trasformerà la chiamata in una descrizione di lista semanticamente equivalente.
<li>In contesti come i cicli <code>for</code>, che iterano comunque attraverso l’intera sequenza, non sono necessari cambiamenti.
<li>Anche in questo caso non sono necessari cambiamenti, perché la descrizione di lista itererà attraverso l’intera sequenza, potendolo fare altrettanto bene sia che <code>filter()</code> restituisca un iteratore sia che restituisca una lista.
</ol>
<h2 id=map>La funzione globale <code>map()</code></h2>
<p>In maniera molto simile a <a href=#filter><code>filter()</code></a>, la funzione <code><dfn>map</dfn>()</code> ora restituisce un iteratore. (In Python 2 restituiva una lista.)
<table>
<tr><th>Note
<th>Python 2
<th>Python 3
<tr><th>①
<td><code class=pp>map(a_function, 'PapayaWhip')</code>
<td><code class=pp>list(map(a_function, 'PapayaWhip'))</code>
<tr><th>②
<td><code class=pp>map(None, 'PapayaWhip')</code>
<td><code class=pp>list('PapayaWhip')</code>
<tr><th>③
<td><code class=pp>map(lambda x: x+1, range(42))</code>
<td><code class=pp>[x+1 for x in range(42)]</code>
<tr><th>④
<td><code class=pp>for i in map(a_function, a_sequence):</code>
<td><i>nessuna modifica</i>
<tr><th>⑤
<td><code class=pp>[i for i in map(a_function, a_sequence)]</code>
<td><i>nessuna modifica</i>
</table>
<ol>
<li>Come con <code>filter()</code>, nel caso più basilare <code>2to3</code> circonderà la chiamata a <code>map()</code> con una chiamata a <code>list()</code>.
<li>La sintassi speciale di <code>map(None, ...)</code>, cioè la funzione identità, sarà convertita da <code>2to3</code> in una chiamata a <code>list()</code> equivalente.
<li>Se il primo argomento di <code>map()</code> è una funzione lambda, <code>2to3</code> la convertirà in una descrizione di lista semanticamente equivalente.
<li>In contesti come i cicli <code>for</code>, che iterano comunque attraverso l’intera sequenza, non sono necessari cambiamenti.
<li>Anche in questo caso non sono necessari cambiamenti, perché la descrizione di lista itererà attraverso l’intera sequenza, potendolo fare altrettanto bene sia che <code>map()</code> restituisca un iteratore sia che restituisca una lista.
</ol>
<h2 id=reduce>La funzione globale <code>reduce()</code></h2>
<p>In Python 3 la funzione <code><dfn>reduce</dfn>()</code> è stata rimossa dallo spazio di nomi globale e collocata nel modulo <code>functools</code>.
<table>
<tr><th>Note
<th>Python 2
<th>Python 3
<tr><th>
<td><code class=pp>reduce(a, b, c)</code>
<td><pre class=pp><code>from functools import reduce
reduce(a, b, c)</code></pre>
</table>
<h2 id=apply>La funzione globale <code>apply()</code></h2>
<p>Python 2 aveva una funzione globale chiamata <code><dfn>apply</dfn>()</code>, che prende una funzione <var>f</var> e una lista <code>[a, b, c]</code> e restituisce <code>f(a, b, c)</code>. Potete ottenere la stessa cosa chiamando la funzione direttamente e passandole la lista degli argomenti preceduta da un asterisco. In Python 3 la funzione <code>apply()</code> non esiste più, perciò dovete usare la notazione con l’asterisco.
<table>
<tr><th>Note
<th>Python 2
<th>Python 3
<tr><th>①
<td><code class=pp>apply(a_function, a_list_of_args)</code>
<td><code class=pp>a_function(*a_list_of_args)</code>
<tr><th>②
<td><code class=pp>apply(a_function, a_list_of_args, a_dictionary_of_named_args)</code>
<td><code class=pp>a_function(*a_list_of_args, **a_dictionary_of_named_args)</code>
<tr><th>③
<td><code class=pp>apply(a_function, a_list_of_args + z)</code>
<td><code class=pp>a_function(*a_list_of_args + z)</code>
<tr><th>④
<td><code class=pp>apply(aModule.a_function, a_list_of_args)</code>
<td><code class=pp>aModule.a_function(*a_list_of_args)</code>
</table>
<ol>
<li>Nella forma più semplice, potete chiamare una funzione con una lista di argomenti (una lista reale come <code>[a, b, c]</code>) facendo precedere la lista da un asterisco (<code>*</code>). Questa forma è esattamente equivalente alla vecchia funzione <code>apply()</code> di Python 2.
<li>In Python 2 la funzione <code>apply()</code> poteva in realtà accettare tre parametri: una funzione, una lista di argomenti e un dizionario di argomenti con nome. In Python 3 potete ottenere la stessa cosa facendo precedere la lista di argomenti da un asterisco (<code>*</code>) e il dizionario di argomenti con nome da due asterischi (<code>**</code>).
<li>L’operatore <code>+</code>, usato qui per concatenare liste, ha precedenza sull’operatore <code>*</code>, quindi non c’è bisogno di parentesi aggiuntive attorno ad <code>a_list_of_args + z</code>.
<li>Lo script <code>2to3</code> è abbastanza scaltro da convertire chiamate complesse ad <code>apply()</code>, comprese chiamate a funzioni contenute in moduli importati.
</ol>
<h2 id=intern>La funzione globale <code>intern()</code></h2>
<p>In Python 2 potevate chiamare la funzione <code><dfn>intern</dfn>()</code> su una stringa per memorizzarla in una tabella interna all’interprete allo scopo di ottimizzare le prestazioni. In Python 3 la funzione <code>intern()</code> è stata spostata nel modulo <code>sys</code>.
<table>
<tr><th>Note
<th>Python 2
<th>Python 3
<tr><th>
<td><code class=pp>intern(aString)</code>
<td><code class=pp>sys.intern(aString)</code>
</table>
<h2 id=exec>L’istruzione <code>exec</code></h2>
<p>Esattamente come <a href=#print>l’istruzione <code>print</code></a> è diventata una funzione in Python 3, così è successo anche all’istruzione <code><dfn>exec</dfn></code>. La funzione <code>exec()</code> prende una stringa che contiene codice Python arbitrario e la esegue come se fosse un’altra istruzione o espressione. <code>exec()</code> è come <a href=uso-avanzato-degli-iteratori.html#eval><code>eval()</code></a>, ma ancora più potente e pericolosa. La funzione <code>eval()</code> può solo valutare una singola espressione, ma <code>exec()</code> può eseguire molteplici istruzioni, importazioni, dichiarazioni di funzione — essenzialmente un intero programma Python in una stringa.
<table>
<tr><th>Note
<th>Python 2
<th>Python 3
<tr><th>①
<td><code class=pp>exec codeString</code>
<td><code class=pp>exec(codeString)</code>
<tr><th>②
<td><code class=pp>exec codeString in a_global_namespace</code>
<td><code class=pp>exec(codeString, a_global_namespace)</code>
<tr><th>③
<td><code class=pp>exec codeString in a_global_namespace, a_local_namespace</code>
<td><code class=pp>exec(codeString, a_global_namespace, a_local_namespace)</code>
</table>
<ol>
<li>Nella sua forma più semplice, lo script <code>2to3</code> racchiude semplicemente tra parentesi il codice sotto forma di stringa, dato che <code>exec()</code> è ora una funzione invece di un’istruzione.
<li>La vecchia istruzione <code>exec</code> poteva utilizzare uno spazio di nomi per rappresentare un ambiente privato di nomi globali nel quale il codice sotto forma di stringa sarebbe stato eseguito. Per fare la stessa cosa in Python 3 basta passare lo spazio di nomi alla funzione <code>exec()</code> come secondo argomento.
<li>In maniera ancora più elaborata, la vecchia istruzione <code>exec</code> poteva anche utilizzare uno spazio di nomi locali (come le variabili definite nell’ambito di una funzione). In Python 3 la funzione <code>exec()</code> può fare anche questo.
</ol>
<h2 id=execfile>L’istruzione <code>execfile</code></h2>
<p>Come la vecchia <a href=#exec>istruzione <code>exec</code></a>, anche la vecchia istruzione <code>execfile</code> esegue stringhe come se fossero codice Python. Laddove <code>exec</code> prendeva una stringa, <code>execfile</code> prendeva un nome di file. In Python 3 l’istruzione <code>execfile</code> è stata eliminata. Se avete davvero bisogno di eseguire un file di codice Python (ma non siete disposti semplicemente a importarlo) potete ottenere lo stesso effetto aprendo il file, leggendone il contenuto, chiamando la funzione globale <code>compile()</code> per obbligare l’interprete Python a compilare il codice e infine utilizzando la nuova funzione <code>exec()</code>.
<table>
<tr><th>Note
<th>Python 2
<th>Python 3
<tr><th>
<td><code class=pp><dfn>execfile</dfn>('nome_di_file')</code>
<td><code class=pp>exec(compile(open('nome_di_file').read(), 'nome_di_file', 'exec'))</code>
</table>
<h2 id=repr>I letterali <code>repr</code> (i backtick)</h2>
<p>Python 2 utilizzava una speciale sintassi per ottenere una rappresentazione di qualsiasi oggetto racchiudendo quell’oggetto tra <dfn>backtick</dfn> (come <code>`x`</code>). In Python 3 questa possibilità esiste ancora, ma dovete usare la funzione globale <code>repr()</code> al posto dei backtick.
<table>
<tr><th>Note
<th>Python 2
<th>Python 3
<tr><th>①
<td><code class=pp>`x`</code>
<td><code class=pp>repr(x)</code>
<tr><th>②
<td><code class=pp>`'PapayaWhip' + `2``</code>
<td><code class=pp>repr('PapayaWhip' + repr(2))</code>
</table>
<ol>
<li>Ricordate, <var>x</var> può essere qualsiasi cosa — una classe, una funzione, un modulo, un tipo di dato primitivo, <i class=baa>&</i>c. La funzione <code>repr()</code> lavora su tutto.
<li>In Python 2 i backtick potevano essere annidati, producendo questo tipo di espressioni confuse (ma valide). Lo strumento <code>2to3</code> è abbastanza scaltro da convertire questi casi in chiamate annidate a <code>repr()</code>.
</ol>
<h2 id=except>L’istruzione <code>try...except</code></h2>
<p>La sintassi per <a href=il-vostro-primo-programma-python.html#exceptions>catturare le <dfn>eccezioni</dfn></a> è leggermente cambiata tra Python 2 e Python 3.
<table>
<tr><th>Note
<th>Python 2
<th>Python 3
<tr><th>①
<td><pre class=pp><code>try:
import mymodule
<dfn>except</dfn> ImportError, e
pass</code></pre>
<td><pre class=pp><code>try:
import mymodule
except ImportError as e:
pass</code></pre>
<tr><th>②
<td><pre class=pp><code>try:
import mymodule
except (RuntimeError, ImportError), e
pass</code></pre>
<td><pre class=pp><code>try:
import mymodule
except (RuntimeError, ImportError) as e:
pass</code></pre>
<tr><th>③
<td><pre class=pp><code>try:
import mymodule
except ImportError:
pass</code></pre>
<td><i>no change</i>
<tr><th>④
<td><pre class=pp><code>try:
import mymodule
except:
pass</code></pre>
<td><i>no change</i>
</table>
<ol>
<li>Invece di una virgola dopo il tipo dell’eccezione, Python 3 usa la nuova parola chiave <code>as</code>.
<li>La parola chiave <code>as</code> funziona anche per catturare più tipi di eccezione alla volta.
<li>Se catturate un’eccezione ma in realtà non vi interessa accedere all’oggetto <dfn>eccezione</dfn> in sé, la sintassi è identica tra Python 2 e Python 3.
<li>Similmente, se usate un’istruzione <code>except</code> vuota per catturare <em>tutte</em> le eccezioni, la sintassi è identica.
</ol>
<blockquote class=note>
<p><span class=u>☞</span>Non dovreste mai usare un’istruzione <code>except</code> vuota per catturare <em>tutte</em> le eccezioni quando importate moduli (o nella maggior parte delle altre occasioni). Se lo fate, rischiate di catturare anche eccezioni come <code>KeyboardInterrupt</code> (se l’utente ha premuto <kbd>Ctrl-C</kbd> per interrompere il programma) rendendo in questo modo molto più difficile effettuare il debug degli errori.
</blockquote>
<h2 id=raise>L’istruzione <code>raise</code></h2>
<p>La sintassi per <a href=il-vostro-primo-programma-python.html#exceptions>sollevare le vostre eccezioni</a> è leggermente cambiata tra Python 2 e Python 3.
<table>
<tr><th>Note
<th>Python 2
<th>Python 3
<tr><th>①
<td><code class=pp><dfn>raise</dfn> MyException</code>
<td><i>nessuna modifica</i>
<tr><th>②
<td><code class=pp>raise MyException, 'messaggio di errore'</code>
<td><code class=pp>raise MyException('messaggio di errore')</code>
<tr><th>③
<td><code class=pp>raise MyException, 'messaggio di errore', a_traceback</code>
<td><code class=pp>raise MyException('messaggio di errore').with_traceback(a_traceback)</code>
<tr><th>④
<td><code class=pp>raise 'messaggio di errore'</code>
<td><i>non supportato</i>
</table>
<ol>
<li>Nella sua forma più semplice, cioè sollevare un’eccezione senza un messaggio personalizzato, la sintassi è rimasta invariata.
<li>Il cambiamento si nota quando volete sollevare un’eccezione con un messaggio personalizzato. Python 2 separava con una virgola la classe dell’eccezione e il messaggio, mentre Python 3 passa il messaggio di errore come un parametro.
<li>Python 2 supportava una sintassi più complessa per sollevare un’eccezione con una <i>traceback</i> (la traccia dello stack di esecuzione) personalizzata. Potete farlo anche in Python 3, ma la sintassi è abbastanza differente.
<li>In Python 2 potevate sollevare un’eccezione senza alcuna classe, utilizzando semplicemente un messaggio di errore. In Python 3 questo non è più possibile. <code>2to3</code> vi avvertirà che non è in grado di correggere automaticamente questo caso.
</ol>
<h2 id=throw>Il metodo <code>throw</code> dei generatori</h2>
<p>In Python 2 i generatori avevano un metodo <code><dfn>throw</dfn>()</code>. Chiamare <code>a_generator.throw()</code> solleva un’eccezione nel punto in cui il generatore è stato sospeso, poi restituisce il valore successivo prodotto dalla funzione generatrice. In Python 3 questa funzionalità è ancora disponibile, ma la sintassi è leggermente diversa.
<table>
<tr><th>Note
<th>Python 2
<th>Python 3
<tr><th>①
<td><code class=pp>a_generator.throw(MyException)</code>
<td><i>nessuna modifica</i>
<tr><th>②
<td><code class=pp>a_generator.throw(MyException, 'messaggio di errore')</code>
<td><code class=pp>a_generator.throw(MyException('messaggio di errore'))</code>
<tr><th>③
<td><code class=pp>a_generator.throw('messaggio di errore')</code>
<td><i>non supportato</i>
</table>
<ol>
<li>Nella sua forma più semplice, un generatore lancia un’eccezione senza un messaggio di errore personalizzato. In questo caso la sintassi non è cambiata nel passaggio da Python 2 a Python 3.
<li>Se il generatore lancia un’eccezione <em>con</em> un messaggio di errore personalizzato, allora dovete passare la stringa di errore all’eccezione quando la create.
<li>Python 2 supportava anche il lancio di un’eccezione utilizzando <em>solo</em> un messaggio di errore personalizzato. Python 3 non lo supporta e lo script <code>2to3</code> visualizzerà un avvertimento dicendovi che avrete bisogno di correggere manualmente questo codice.
</ol>
<h2 id=xrange>La funzione globale <code>xrange()</code></h2>
<p>In Python 2 c’erano due modi per ottenere una lista di numeri: <code><dfn>range</dfn>()</code>, che restituiva una lista, e <code><dfn>xrange</dfn>()</code>, che restituiva un iteratore. In Python 3 <code>range()</code> restituisce un iteratore e <code>xrange()</code> non esiste più.
<table>
<tr><th>Note
<th>Python 2
<th>Python 3
<tr><th>①
<td><code class=pp>xrange(10)</code>
<td><code class=pp>range(10)</code>
<tr><th>②
<td><code class=pp>a_list = range(10)</code>
<td><code class=pp>a_list = list(range(10))</code>
<tr><th>③
<td><code class=pp>[i for i in xrange(10)]</code>
<td><code class=pp>[i for i in range(10)]</code>
<tr><th>④
<td><code class=pp>for i in range(10):</code>
<td><i>nessuna modifica</i>
<tr><th>⑤
<td><code class=pp>sum(range(10))</code>
<td><i>nessuna modifica</i>
</table>
<ol>
<li>Nel caso più semplice, lo script <code>2to3</code> convertirà semplicemente <code>xrange()</code> in <code>range()</code>.
<li>Se il vostro programma in Python 2 usava <code>range()</code>, lo script <code>2to3</code> non sa se avete bisogno di una lista o se un iteratore potrebbe bastare. Pecca per eccesso di prudenza e converte il valore di ritorno in una lista chiamando la funzione <code>list()</code>.
<li>Se la funzione <code>xrange()</code> si trova in una descrizione di lista, lo script <code>2to3</code> è abbastanza scaltro da <em>non</em> racchiudere la funzione <code>range()</code> in una invocazione a <code>list()</code>. La descrizione di lista lavora altrettanto bene con l’iteratore restituito dalla funzione <code>range()</code>.
<li>Similmente, un ciclo <code>for</code> lavora altrettanto bene con un iteratore, quindi non c’è bisogno di cambiare nulla qui.
<li>Anche la funzione <code>sum()</code> lavora altrettanto bene con un iteratore, quindi <code>2to3</code> non effettua alcun cambiamento neanche qui. Come per <a href=#dict>i metodi dei dizionari che restituiscono viste invece di liste</a>, questo si applica a <code>min()</code>, <code>max()</code>, <code>sum()</code>, <code>list()</code>, <code>tuple()</code>, <code>set()</code>, <code>sorted()</code>, <code>any()</code> e <code>all()</code>.
</ol>
<h2 id=raw_input>Le funzioni globali <code>raw_input()</code> e
<code>input()</code></h2>
<p>Python 2 aveva due funzioni globali per chiedere all’utente di inserire dati in ingresso dalla riga di comando. La prima, chiamata <code>input()</code>, si aspettava che l’utente inserisse un’espressione Python (e ne restituiva il risultato). La seconda, chiamata <code><dfn>raw_input</dfn>()</code>, restituiva semplicemente qualsiasi cosa l’utente avesse digitato. Questo comportamento era fonte di terribile confusione per i principianti e generalmente considerato come un “neo” del linguaggio. Python 3 asporta questo neo rinominando <code>raw_input()</code> a <code>input()</code>, in modo che funzioni come ci si aspetta intuitivamente che debba funzionare.
<table>
<tr><th>Note
<th>Python 2
<th>Python 3
<tr><th>①
<td><code class=pp>raw_input()</code>
<td><code class=pp>input()</code>
<tr><th>②
<td><code class=pp>raw_input('prompt')</code>
<td><code class=pp>input('prompt')</code>
<tr><th>③
<td><code class=pp>input()</code>
<td><code class=pp>eval(input())</code>
</table>
<ol>
<li>Nella sua forma più semplice, <code>raw_input()</code> diventa <code>input()</code>.
<li>In Python 2 la funzione <code>raw_input()</code> poteva prendere come parametro un prompt, cioè una stringa di caratteri visualizzata per indicare l’attesa di un nuovo ingresso da parte della funzione. Questo parametro è stato mantenuto in Python 3.
<li>Se avete effettivamente bisogno di chiedere all’utente un’espressione Python da valutare, usate la funzione <code>input()</code> e passatene il risultato a <code>eval()</code>.
</ol>
<h2 id=funcattrs>Gli attributi <code>func_*</code> delle funzioni</h2>
<p>In Python 2 il codice all’interno delle funzioni può accedere a particolari attributi della funzione stessa. In Python 3 questi attributi speciali di una funzione sono stati rinominati per renderli consistenti con altri attributi.
<table>
<tr><th>Note
<th>Python 2
<th>Python 3
<tr><th>①
<td><code class=pp>a_function.<dfn>func_name</dfn></code>
<td><code class=pp>a_function.__name__</code>
<tr><th>②
<td><code class=pp>a_function.<dfn>func_doc</dfn></code>
<td><code class=pp>a_function.__doc__</code>
<tr><th>③
<td><code class=pp>a_function.<dfn>func_defaults</dfn></code>
<td><code class=pp>a_function.__defaults__</code>
<tr><th>④
<td><code class=pp>a_function.<dfn>func_dict</dfn></code>
<td><code class=pp>a_function.__dict__</code>
<tr><th>⑤
<td><code class=pp>a_function.<dfn>func_closure</dfn></code>
<td><code class=pp>a_function.__closure__</code>
<tr><th>⑥
<td><code class=pp>a_function.<dfn>func_globals</dfn></code>
<td><code class=pp>a_function.__globals__</code>
<tr><th>⑦
<td><code class=pp>a_function.<dfn>func_code</dfn></code>
<td><code class=pp>a_function.__code__</code>
</table>
<ol>
<li>L’attributo <code>__name__</code> (precedentemente <code>func_name</code>) contiene il nome della funzione.
<li>L’attributo <code>__doc__</code> (precedentemente <code>func_doc</code>) contiene la <code>docstring</code> che avete definito nel codice sorgente della funzione.
<li>L’attributo <code>__defaults__</code> (precedentemente <code>func_defaults</code>) è una tupla contenente i valori predefiniti degli argomenti per quegli argomenti che hanno un valore predefinito.
<li>L’attributo <code>__dict__</code> (precedentemente <code>func_dict</code>) è lo spazio di nomi che supporta la gestione di attributi arbitrari per la funzione.
<li>L’attributo <code>__closure__</code> (precedentemente <code>func_closure</code>) è una tupla di celle che contengono i legami per le variabili libere della funzione.
<li>L’attributo <code>__globals__</code> (precedentemente <code>func_globals</code>) è un riferimento allo spazio di nomi globale del modulo in cui la funzione è stata definita.
<li>L’attributo <code>__code__</code> (precedentemente <code>func_code</code>) è un oggetto codice che rappresenta il corpo della funzione compilata.
</ol>
<h2 id=xreadlines>Il metodo di I/O <code>xreadlines()</code></h2>
<p>In Python 2 gli oggetti file avevano un metodo <code><dfn>xreadlines</dfn>()</code> che restituiva un iteratore per leggere il file una riga alla volta. Questo era utile nei cicli <code>for</code> e in alcuni altri casi. In effetti, era così utile che le ultime versioni di Python 2 hanno aggiunto questa capacità agli oggetti file stessi.
<p>In Python 3 il metodo <code>xreadlines()</code> non esiste più. <code>2to3</code> può correggere i casi più semplici, ma alcuni casi limite richiederanno un intervento manuale.
<table>
<tr><th>Note
<th>Python 2
<th>Python 3
<tr><th>①
<td><code class=pp>for line in a_file.xreadlines():</code>
<td><code class=pp>for line in a_file:</code>
<tr><th>②
<td><code class=pp>for line in a_file.xreadlines(5):</code>
<td><i>nessun cambiamento (guasto)</i>
</table>
<ol>
<li>Se di solito chiamavate <code>xreadlines()</code> senza argomenti, <code>2to3</code> convertirà la chiamata al solo oggetto file. In Python 3, questo è il modo in cui si effettua la stessa operazione: leggere il file una riga alla volta ed eseguire il corpo del ciclo <code>for</code>.
<li>Se di solito chiamavate <code>xreadlines()</code> con un argomento (il numero di righe da leggere alla volta), <code>2to3</code> non vi correggerà e il vostro codice fallirà con un messaggio <code>AttributeError: '_io.TextIOWrapper' object has no attribute 'xreadlines'</code>. Potete manualmente sostituire <code>xreadlines()</code> con <code>readlines()</code> per farlo funzionare in Python 3. (Il metodo <code>readlines()</code> ora restituisce un iteratore, quindi è esattamente tanto efficiente quanto lo era <code>xreadlines()</code> in Python 2.)
</ol>
<p class=c><span style='font-size:56px;line-height:0.88'>☃</span>
<h2 id=tuple_params>Funzioni <code>lambda</code> che accettano una tupla invece di parametri multipli</h2>
<p>In Python 2 potevate definire una funzione <code><dfn>lambda</dfn></code> anonima che accettava diversi parametri scrivendola in modo che accettasse una tupla con uno specifico numero di elementi. In effetti, Python 2 avrebbe “spacchettato” la tupla negli argomenti con nome a cui poi avreste potuto riferirvi (attraverso il nome) all’interno della funzione <code>lambda</code>. In Python 3 potete ancora passare una tupla a una funzione <code>lambda</code>, ma l’interprete Python non spacchetterà la tupla in argomenti con nome. Invece, dovrete riferirvi a ogni argomento tramite l’indice della sua posizione.
<table>
<tr><th>Note
<th>Python 2
<th>Python 3
<tr><th>①
<td><code class=pp>lambda (x,): x + f(x)</code>
<td><code class=pp>lambda x1: x1[0] + f(x1[0])</code>
<tr><th>②
<td><code class=pp>lambda (x, y): x + f(y)</code>
<td><code class=pp>lambda x_y: x_y[0] + f(x_y[1])</code>
<tr><th>③
<td><code class=pp>lambda (x, (y, z)): x + y + z</code>
<td><code class=pp>lambda x_y_z: x_y_z[0] + x_y_z[1][0] + x_y_z[1][1]</code>
<tr><th>④
<td><code class=pp>lambda x, y, z: x + y + z</code>
<td><i>nessuna modifica</i>
</table>
<ol>
<li>Se avete definito una funzione <code>lambda</code> che accetta una tupla composta da un elemento, in Python 3 questa diventerà una <code>lambda</code> con riferimenti a <var>x1[0]</var>. Il nome <var>x1</var> viene generato automaticamente dallo script <code>2to3</code> sulla base degli argomenti con nome nella tupla originale.
<li>La tupla di due elementi <var>(x, y)</var> argomento di una funzione <code>lambda</code> viene convertita a <var>x_y</var> con argomenti posizionali <var>x_y[0]</var> e <var>x_y[1]</var>.
<li>Lo script <code>2to3</code> può perfino gestire funzioni <code>lambda</code> con tuple innestate di argomenti con nome. Il codice Python 3 risultante è leggermente illeggibile, ma funziona allo stesso modo in cui funzionava in Python 2.
<li>Potete definire funzioni <code>lambda</code> che accettano più argomenti. Senza parentesi attorno agli argomenti, Python 2 le tratta semplicemente come funzioni <code>lambda</code> con diversi argomenti, in modo che all’interno della funzione <code>lambda</code> possiate riferirvi agli argomenti tramite il loro nome esattamente come avviene per ogni altra funzione. Questa sintassi funziona ancora in Python 3.
</ol>
<h2 id=methodattrs>Attributi speciali dei metodi</h2>
<p>In Python 2 i metodi di classe possono fare riferimento all’oggetto classe in cui sono definiti così come all’oggetto metodo stesso. <code>im_self</code> è l’istanza dell’oggetto classe; <code>im_func</code> rappresenta l’oggetto funzione; <code>im_class</code> è la classe di <code>im_self</code>. In Python 3 questi attributi speciali dei metodi sono stati rinominati per seguire le convenzioni sui nomi degli altri attributi.
<table>
<tr><th>Note
<th>Python 2
<th>Python 3
<tr><th>
<td><code class=pp>aClassInstance.aClassMethod.<dfn>im_func</dfn></code>
<td><code class=pp>aClassInstance.aClassMethod.__func__</code>
<tr><th>
<td><code class=pp>aClassInstance.aClassMethod.<dfn>im_self</dfn></code>
<td><code class=pp>aClassInstance.aClassMethod.__self__</code>
<tr><th>
<td><code class=pp>aClassInstance.aClassMethod.<dfn>im_class</dfn></code>
<td><code class=pp>aClassInstance.aClassMethod.__self__.__class__</code>
</table>
<h2 id=nonzero>Il metodo speciale <code>__nonzero__</code></h2>
<p>In Python 2 potevate costruire una vostra classe permettendole di essere usata in un contesto logico. Per esempio, potevate istanziare la classe e poi usare l’istanza in un’istruzione <code>if</code>. Per fare questo, definivate un metodo speciale <code>__nonzero__()</code> che restituiva <code>True</code> o <code>False</code> e veniva chiamato ogni volta che l’istanza era usata in un contesto logico. In Python 3 potete ancora farlo, ma il nome del metodo è stato cambiato in <code>__bool__()</code>.
<table>
<tr><th>Note
<th>Python 2
<th>Python 3
<tr><th>①
<td><pre class=pp><code>class A:
def <dfn>__nonzero__</dfn>(self):
pass</code></pre>
<td><pre class=pp><code>class A:
def <dfn>__bool__</dfn>(self):
pass</code></pre>
<tr><th>②
<td><pre class=pp><code>class A:
def __nonzero__(self, x, y):
pass</code></pre>
<td><i>nessuna modifica</i>
</table>
<ol>
<li>Al posto di <code>__nonzero__()</code>, Python 3 chiama il metodo <code>__bool__()</code> per valutare un’istanza in un contesto logico.
<li>Comunque, se avete un metodo <code>__nonzero__()</code> che accetta argomenti, lo strumento <code>2to3</code> presumerà che lo stiate usando per qualche altro scopo e non effettuerà alcun cambiamento.
</ol>
<h2 id=numliterals>Letterali in base otto</h2>
<p>La sintassi per definire numeri in base 8 (<dfn>ottali</dfn>) è leggermente cambiata nel passaggio da Python 2 a Python 3.
<table>
<tr><th>Note
<th>Python 2
<th>Python 3
<tr><th>
<td><code class=pp>x = 0755</code>
<td><code class=pp>x = 0o755</code>
</table>
<h2 id=renames><code>sys.maxint</code></h2>
<p>A causa dell’integrazione tra i tipi <code>long</code> e <code>int</code>, la costante <code>sys.maxint</code> non è più accurata. Dato che il valore potrebbe ancora essere utile per determinare le capacità di una specifica piattaforma, la costante è stata mantenuta ma rinominata in <code>sys.maxsize</code>.
<table>
<tr><th>Note
<th>Python 2
<th>Python 3
<tr><th>①
<td><code class=pp>from sys import <dfn>maxint</dfn></code>
<td><code class=pp>from sys import <dfn>maxsize</dfn></code>
<tr><th>②
<td><code class=pp>a_function(<dfn>sys.maxint</dfn>)</code>
<td><code class=pp>a_function(<dfn>sys.maxsize</dfn>)</code>
</table>
<ol>
<li><code>maxint</code> diventa <code>maxsize</code>.
<li>Ogni uso di <code>sys.maxint</code> diventa <code>sys.maxsize</code>.
</ol>
<h2 id=callable>La funzione globale <code>callable()</code></h2>
<p>In Python 2 potevate contollare se un oggetto era invocabile (come una funzione) tramite la funzione globale <code><dfn>callable</dfn>()</code>. In Python 3 questa funzione globale è stata eliminata. Per controllare se un oggetto è invocabile, verificate l’esistenza del metodo speciale <code>__call__()</code>.