Differenze

Queste sono le differenze tra la revisione selezionata e la versione attuale della pagina.

Link a questa pagina di confronto

Entrambe le parti precedenti la revisioneRevisione precedente
Prossima revisione
Revisione precedente
python:porting_python_2_to_pyton_3 [2020/01/22 15:19] – WIP apressatopython:porting_python_2_to_pyton_3 [2020/01/22 18:01] (versione attuale) – WIP apressato
Linea 1: Linea 1:
 ====== Porting da Python 2 a Python 3  ======  ====== Porting da Python 2 a Python 3  ====== 
  
-<WRAP center round important 60%> 
-***WIP***: Quello seguente è un articolo in divenire 
-</WRAP> 
  
  
Linea 539: Linea 536:
  
 ===== Dictionaries ===== ===== Dictionaries =====
 +
 +<code python>
 +heights = {'Fred': 175, 'Anne': 166, 'Joe': 192}
 +</code>
 +
 +==== Scorrere le chiavi / i valori / gli elementi di un dizionario ====
 +=== Le chiavi ===
 +== Python 2 ==
 +<code python>
 +for key in heights.iterkeys():
 +    ...
 +</code>
 +
 +== Python 2 e 3 ==
 +<code python>
 +for key in heights:
 +    ...
 +</code>
 +
 +=== I Valori ===
 +== Python 2 ==
 +<code python>
 +for value in heights.itervalues():
 +    ...
 +</code>
 +
 +== Python 2 e 3 ==
 +<code python>
 +#Opzione 0: Sconsigliata
 +for value in heights.values():    # Maggiore consumo di memoria in Py2
 +    ...
 +</code>
 +
 +<code python>
 +# Opzione 1
 +from builtins import dict
 +
 +heights = dict(Fred=175, Anne=166, Joe=192)
 +for key in heights.values():    # efficiente in Py2 e Py3
 +</code>
 +
 +<code python>
 +# Opzione 2
 +from builtins import itervalues
 +
 +for key in itervalues(heights):
 +    ...
 +</code>
 +
 +=== Gli Elementi ===
 +== Python 2 ==
 +<code python>
 +for (key, value) in heights.iteritems():
 +    ...
 +</code>
 +
 +== Python 2 e 3 ==
 +<code python>
 +# Opzione 1
 +for (key, value) in heights.items():    # inefficiente in Py2
 +    ...
 +</code>
 +
 +<code python>
 +# Opzione 2
 +from future.utils import viewitems
 +
 +for (key, value) in viewitems(heights):   # si compporta come un set
 +    ...
 +</code>
 +
 +<code python>
 +# Opzione 3
 +from future.utils import iteritems
 +
 +for (key, value) in iteritems(heights):
 +    ...
 +</code>
 +
 +==== Chiavi/Valori/Elementi di un Dizionario come Lista ====
 +=== Chiavi ===
 +== Python 2 ==
 +<code python>
 +keylist = heights.keys()
 +assert isinstance(keylist, list)
 +</code>
 +== Python 2 e 3 ==
 +<code python>
 +keylist = list(heights)
 +assert isinstance(keylist, list)
 +</code>
 +
 +=== Valori ===
 +== Python 2 ==
 +<code python>
 +heights = {'Fred': 175, 'Anne': 166, 'Joe': 192}
 +valuelist = heights.values()
 +assert isinstance(valuelist, list)
 +</code>
 +== Python 2 e 3 ==
 +<code python>
 +# Opzione 1
 +valuelist = list(heights.values())    # inefficiente in Py2
 +</code>
 +
 +<code python>
 +# Opzione 2
 +from builtins import dict
 +
 +heights = dict(Fred=175, Anne=166, Joe=192)
 +valuelist = list(heights.values())
 +</code>
 +
 +<code python>
 +# Opzione 3
 +from future.utils import listvalues
 +
 +valuelist = listvalues(heights)
 +</code>
 +
 +<code python>
 +# Opzione 4
 +from future.utils import itervalues
 +
 +valuelist = list(itervalues(heights))
 +</code>
 +
 +=== Elementi ===
 +== Python 2 e 3 ==
 +<code python>
 +# Opzione 1
 +itemlist = list(heights.items())    # inefficiente in Py2
 +</code>
 +
 +<code python>
 +# Opzione 2
 +from future.utils import listitems
 +
 +itemlist = listitems(heights)
 +</code>
 +
 +<code python>
 +# Opzione 3
 +from future.utils import iteritems
 +
 +itemlist = list(iteritems(heights))
 +</code>
  
 ===== Imports relativi ad un package ===== ===== Imports relativi ad un package =====
Linea 565: Linea 709:
 </code> </code>
 ===== Altre variazioni ai builtins ===== ===== Altre variazioni ai builtins =====
 +==== File IO con open() ====
 +<code python>
 +# Python 2 only
 +f = open('myfile.txt')
 +data = f.read()              # as a byte string
 +text = data.decode('utf-8')
 +
 +# Python 2 and 3: alternative 1
 +from io import open
 +f = open('myfile.txt', 'rb')
 +data = f.read()              # as bytes
 +text = data.decode('utf-8' # unicode, not bytes
 +
 +# Python 2 and 3: alternative 2
 +from io import open
 +f = open('myfile.txt', encoding='utf-8')
 +text = f.read()    # unicode, not bytes
 +</code>
 +
 +==== reduce() ====
 +<code python>
 +# Python 2 only:
 +assert reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) == 1+2+3+4+5
 +
 +
 +# Python 2 and 3:
 +from functools import reduce
 +
 +assert reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) == 1+2+3+4+5
 +</code>
 +
 +==== file() ====
 +<code python>
 +# Python 2 only:
 +f = file(pathname)
 +</code>
 +
 +<code python>
 +# Python 2 and 3:
 +f = open(pathname)
 +
 +# But preferably, use this:
 +from io import open
 +f = open(pathname, 'rb'  # if f.read() should return bytes
 +# or
 +f = open(pathname, 'rt'  # if f.read() should return unicode text
 +</code>
 +
 +==== exec ====
 +<code python>
 +# Python 2 only:
 +exec 'x = 10'
 +
 +# Python 2 and 3:
 +exec('x = 10')
 +</code>
 +
 +<code python>
 +# Python 2 only:
 +g = globals()
 +exec 'x = 10' in g
 +
 +# Python 2 and 3:
 +g = globals()
 +exec('x = 10', g)
 +</code>
 +
 +<code python>
 +# Python 2 only:
 +l = locals()
 +exec 'x = 10' in g, l
 +
 +# Python 2 and 3:
 +exec('x = 10', g, l)
 +</code>
 +
 +==== execfile() ====
 +<code python>
 +# Python 2 only:
 +execfile('myfile.py')
 +
 +
 +# Python 2 and 3: alternative 1
 +from past.builtins import execfile
 +
 +execfile('myfile.py')
 +
 +
 +# Python 2 and 3: alternative 2
 +exec(compile(open('myfile.py').read()))
 +
 +
 +# This can sometimes cause this:
 +#     SyntaxError: function ... uses import * and bare exec ...
 +# See https://github.com/PythonCharmers/python-future/issues/37
 +</code>
 +
 +==== unichr() ====
 +<code python>
 +# Python 2 only:
 +assert unichr(8364) == '€'
 +
 +# Python 3 only:
 +assert chr(8364) == '€'
 +
 +# Python 2 and 3:
 +from builtins import chr
 +assert chr(8364) == '€'
 +</code>
 +
 +==== intern() ====
 +<code python>
 +# Python 2 only:
 +intern('mystring')
 +
 +
 +# Python 3 only:
 +from sys import intern
 +intern('mystring')
 +
 +
 +# Python 2 and 3: alternative 1
 +from past.builtins import intern
 +intern('mystring')
 +
 +
 +# Python 2 and 3: alternative 2
 +from six.moves import intern
 +intern('mystring')
 +
 +
 +# Python 2 and 3: alternative 3
 +from future.standard_library import install_aliases
 +install_aliases()
 +from sys import intern
 +intern('mystring')
 +
 +
 +# Python 2 and 3: alternative 4
 +try:
 +    from sys import intern
 +except ImportError:
 +    pass
 +intern('mystring')
 +</code>
 +
 +==== apply() ====
 +<code python>
 +args = ('a', 'b')
 +kwargs = {'kwarg1': True}
 +
 +
 +# Python 2 only:
 +apply(f, args, kwargs)
 +
 +
 +# Python 2 and 3: alternative 1
 +f(*args, **kwargs)
 +
 +
 +# Python 2 and 3: alternative 2
 +from past.builtins import apply
 +apply(f, args, kwargs)
 +</code>
 +
 +==== chr() ====
 +<code python>
 +# Python 2 only:
 +assert chr(64) == b'@'
 +assert chr(200) == b'\xc8'
 +
 +
 +# Python 3 only: option 1
 +assert chr(64).encode('latin-1') == b'@'
 +assert chr(0xc8).encode('latin-1') == b'\xc8'
 +
 +
 +# Python 2 and 3: option 1
 +from builtins import chr
 +
 +assert chr(64).encode('latin-1') == b'@'
 +assert chr(0xc8).encode('latin-1') == b'\xc8'
 +
 +
 +# Python 3 only: option 2
 +assert bytes([64]) == b'@'
 +assert bytes([0xc8]) == b'\xc8'
 +
 +
 +# Python 2 and 3: option 2
 +from builtins import bytes
 +
 +assert bytes([64]) == b'@'
 +assert bytes([0xc8]) == b'\xc8'
 +</code>
 +
 +==== cmp() ====
 +<code python>
 +# Python 2 only:
 +assert cmp('a', 'b') < 0 and cmp('b', 'a') > 0 and cmp('c', 'c') == 0
 +
 +
 +# Python 2 and 3: alternative 1
 +from past.builtins import cmp
 +assert cmp('a', 'b') < 0 and cmp('b', 'a') > 0 and cmp('c', 'c') == 0
 +
 +
 +# Python 2 and 3: alternative 2
 +cmp = lambda(x, y): (x > y) - (x < y)
 +assert cmp('a', 'b') < 0 and cmp('b', 'a') > 0 and cmp('c', 'c') == 0
 +</code>
 +
 +==== reload() ====
 +<code python>
 +# Python 2 only:
 +reload(mymodule)
 +
 +
 +# Python 2 and 3
 +from imp import reload
 +reload(mymodule)
 +</code>
  
 ===== Standard library ===== ===== Standard library =====
 +==== dbm modules ====
 +<code python>
 +# Python 2 only
 +import anydbm
 +import whichdb
 +import dbm
 +import dumbdbm
 +import gdbm
  
 +# Python 2 and 3: alternative 1
 +from future import standard_library
 +standard_library.install_aliases()
  
-===== Modernize =====+import dbm 
 +import dbm.ndbm 
 +import dbm.dumb 
 +import dbm.gnu
  
 +# Python 2 and 3: alternative 2
 +from future.moves import dbm
 +from future.moves.dbm import dumb
 +from future.moves.dbm import ndbm
 +from future.moves.dbm import gnu
  
 +# Python 2 and 3: alternative 3
 +from six.moves import dbm_gnu
 +# (others not supported)
 +</code>
  
 +==== commands / subprocess modules ====
 +<code python>
 +# Python 2 only
 +from commands import getoutput, getstatusoutput
  
 +# Python 2 and 3
 +from future import standard_library
 +standard_library.install_aliases()
  
 +from subprocess import getoutput, getstatusoutput
 +</code>
  
 +==== subprocess.check_output() ====
 +<code python>
 +# Python 2.7 and above
 +from subprocess import check_output
  
 +# Python 2.6 and above: alternative 1
 +from future.moves.subprocess import check_output
 +
 +# Python 2.6 and above: alternative 2
 +from future import standard_library
 +standard_library.install_aliases()
 +
 +from subprocess import check_output
 +</code>
 +
 +==== Collections: Counter and OrderedDict ====
 +<code python>
 +# Python 2.7 and above
 +from collections import Counter, OrderedDict
 +
 +# Python 2.6 and above: alternative 1
 +from future.moves.collections import Counter, OrderedDict
 +
 +# Python 2.6 and above: alternative 2
 +from future import standard_library
 +standard_library.install_aliases()
 +
 +from collections import Counter, OrderedDict
 +</code>
 +
 +==== StringIO module ====
 +<code python>
 +# Python 2 only
 +from StringIO import StringIO
 +from cStringIO import StringIO
 +
 +# Python 2 and 3
 +from io import BytesIO
 +# and refactor StringIO() calls to BytesIO() if passing byte-strings
 +</code>
 +
 +==== http module ====
 +<code python>
 +# Python 2 only:
 +import httplib
 +import Cookie
 +import cookielib
 +import BaseHTTPServer
 +import SimpleHTTPServer
 +import CGIHttpServer
 +
 +# Python 2 and 3 (after ``pip install future``):
 +import http.client
 +import http.cookies
 +import http.cookiejar
 +import http.server
 +</code>
 +
 +==== xmlrpc module ====
 +<code python>
 +# Python 2 only:
 +import DocXMLRPCServer
 +import SimpleXMLRPCServer
 +
 +# Python 2 and 3 (after ``pip install future``):
 +import xmlrpc.server
 +</code>
 +
 +<code python>
 +# Python 2 only:
 +import xmlrpclib
 +
 +# Python 2 and 3 (after ``pip install future``):
 +import xmlrpc.client
 +</code>
 +
 +==== html escaping and entities ====
 +<code python>
 +# Python 2 and 3:
 +from cgi import escape
 +
 +# Safer (Python 2 and 3, after ``pip install future``):
 +from html import escape
 +
 +# Python 2 only:
 +from htmlentitydefs import codepoint2name, entitydefs, name2codepoint
 +
 +# Python 2 and 3 (after ``pip install future``):
 +from html.entities import codepoint2name, entitydefs, name2codepoint
 +</code>
 +
 +==== html parsing ====
 +<code python>
 +# Python 2 only:
 +from HTMLParser import HTMLParser
 +
 +# Python 2 and 3 (after ``pip install future``)
 +from html.parser import HTMLParser
 +
 +# Python 2 and 3 (alternative 2):
 +from future.moves.html.parser import HTMLParser
 +</code>
 +
 +==== urllib module ====
 +''urllib'' è uno dei moduli più complessi da usare in compatibilità fra 2 e 3.
 +
 +<code python>
 +# Python 2 only:
 +from urlparse import urlparse
 +from urllib import urlencode
 +from urllib2 import urlopen, Request, HTTPError
 +</code>
 +
 +<code python>
 +# Python 3 only:
 +from urllib.parse import urlparse, urlencode
 +from urllib.request import urlopen, Request
 +from urllib.error import HTTPError
 +</code>
 +
 +<code python>
 +# Python 2 and 3: easiest option
 +from future.standard_library import install_aliases
 +install_aliases()
 +
 +from urllib.parse import urlparse, urlencode
 +from urllib.request import urlopen, Request
 +from urllib.error import HTTPError
 +</code>
 +
 +<code python>
 +# Python 2 and 3: alternative 2
 +from future.standard_library import hooks
 +
 +with hooks():
 +    from urllib.parse import urlparse, urlencode
 +    from urllib.request import urlopen, Request
 +    from urllib.error import HTTPError
 +</code>
 +
 +<code python>
 +# Python 2 and 3: alternative 3
 +from future.moves.urllib.parse import urlparse, urlencode
 +from future.moves.urllib.request import urlopen, Request
 +from future.moves.urllib.error import HTTPError
 +</code>
 +
 +<code python>
 +# Python 2 and 3: alternative 4
 +try:
 +    from urllib.parse import urlparse, urlencode
 +    from urllib.request import urlopen, Request
 +    from urllib.error import HTTPError
 +except ImportError:
 +    from urlparse import urlparse
 +    from urllib import urlencode
 +    from urllib2 import urlopen, Request, HTTPError
 +</code>
 +
 +==== Tkinter ====
 +<code python>
 +# Python 2 only:
 +import Tkinter
 +import Dialog
 +import FileDialog
 +import ScrolledText
 +import SimpleDialog
 +import Tix
 +import Tkconstants
 +import Tkdnd
 +import tkColorChooser
 +import tkCommonDialog
 +import tkFileDialog
 +import tkFont
 +import tkMessageBox
 +import tkSimpleDialog
 +import ttk
 +
 +# Python 2 and 3 (after ``pip install future``):
 +import tkinter
 +import tkinter.dialog
 +import tkinter.filedialog
 +import tkinter.scrolledtext
 +import tkinter.simpledialog
 +import tkinter.tix
 +import tkinter.constants
 +import tkinter.dnd
 +import tkinter.colorchooser
 +import tkinter.commondialog
 +import tkinter.filedialog
 +import tkinter.font
 +import tkinter.messagebox
 +import tkinter.simpledialog
 +import tkinter.ttk
 +</code>
 +
 +==== socketserver ====
 +<code python>
 +# Python 2 only:
 +import SocketServer
 +
 +# Python 2 and 3 (after ``pip install future``):
 +import socketserver
 +</code>
 +
 +==== copy_reg, copyreg ====
 +<code python>
 +# Python 2 only:
 +import copy_reg
 +
 +# Python 2 and 3 (after ``pip install future``):
 +import copyreg
 +</code>
 +
 +==== configparser ====
 +<code python>
 +# Python 2 only:
 +from ConfigParser import ConfigParser
 +
 +# Python 2 and 3 (after ``pip install configparser``):
 +from configparser import ConfigParser
 +</code>
 +
 +==== queue ====
 +<code python>
 +# Python 2 only:
 +from Queue import Queue, heapq, deque
 +
 +# Python 2 and 3 (after ``pip install future``):
 +from queue import Queue, heapq, deque
 +</code>
 +
 +==== repr, reprlib ====
 +<code python>
 +# Python 2 only:
 +from repr import aRepr, repr
 +
 +# Python 2 and 3 (after ``pip install future``):
 +from reprlib import aRepr, repr
 +</code>
 +
 +==== UserDict, UserList, UserString ====
 +<code python>
 +# Python 2 only:
 +from UserDict import UserDict
 +from UserList import UserList
 +from UserString import UserString
 +
 +
 +# Python 3 only:
 +from collections import UserDict, UserList, UserString
 +
 +
 +# Python 2 and 3: alternative 1
 +from future.moves.collections import UserDict, UserList, UserString
 +
 +
 +# Python 2 and 3: alternative 2
 +from six.moves import UserDict, UserList, UserString
 +
 +
 +# Python 2 and 3: alternative 3
 +from future.standard_library import install_aliases
 +install_aliases()
 +from collections import UserDict, UserList, UserString
 +</code>
 +
 +==== itertools: filterfalse, zip_longest ====
 +<code python>
 +# Python 2 only:
 +from itertools import ifilterfalse, izip_longest
 +
 +# Python 3 only:
 +from itertools import filterfalse, zip_longest
 +
 +# Python 2 and 3: alternative 1
 +from future.moves.itertools import filterfalse, zip_longest
 +
 +# Python 2 and 3: alternative 2
 +from six.moves import filterfalse, zip_longest
 +
 +# Python 2 and 3: alternative 3
 +from future.standard_library import install_aliases
 +install_aliases()
 +from itertools import filterfalse, zip_longest
 +</code>
 +
 +
 +
 +===== Python-Modernize =====
 +
 +==== Scopo del progetto ====
 +Questa libreria è un wrapper attorno a ''lib2to3'' che serve a rendere il codice Python 2 più moderno in ottica di portarlo su Python 3.
 +
 +Il comando python-modernize funziona come 2to3. Ecco come riscrivere un singolo file:
 +
 +<code bash>
 +python-modernize -w example.py
 +</code>
 +
 +Il sito Web del progetto è disponibile su [[https://github.com/python-modernize/python-modernize|GitHub]] e il nome del progetto PyPI è [[https://pypi.python.org/pypi/modernize|modernize]]
 +
 +==== Una nota sulla gestione delle stringhe ====
 +  * Di default modernize non cambia le stringhe Unicode. \\ Questa è l'opzione più semplice se vuoi supportare Python 3.x e versioni successive insieme a Python 2.
 +  * In alternativa, c'è il flag ''**--six-unicode**'' che avvolgerà le stringhe Unicode con la funzione helper **six.u()** usando il fixer contenuto in ''libmodernize.fixes.fix_unicode''.\\ Ciò è utile se si desidera supportare Python 3.1 e Python 3.2 senza grandi cambiamenti.
 +  * L'ultima alternativa è il flag ''**--future-unicode**'' che importa gli ''unicode_literals'' dal modulo **<nowiki>__future__</nowiki>** usando il fixer contenuto in ''libmodernize.fixes.fix_unicode_future''.\\ Ciò richiede Python 2.6 e versioni successive e richiederà di contrassegnare le bytestring con b '' e le stringhe native in str('') o qualcosa di simile che sopravviva alla trasformazione.
 +
 +==== Preparazione ====
 +Dal prompt dei comandi lanciare
 +<code bash>
 +pip --install modernize
 +</code>
 +Al termine dell'installazione avrete a disposizione l'eseguibile **python-modernize**
 +
 +==== Batch di conversione ====
 +<code batch>
 +set mydatetime=%date:~-4%%date:~-7,2%%date:~-10,2%_%time:~0,2%%time:~3,2%%time:~6,2%
 +set logpath=.\Logs
 +set logfile=%logpath%\Migrate_%Application%_2to3_%mydatetime%.log
 +set RepoPath=path\to\your \web2py\applications
 +set Application=Your_Folder_App_Name
 +
 +IF NOT EXIST %logpath% (
 +  MKDIR %logpath%
 +)
 +
 +(FOR /f "delims=" %%a IN ('DIR %RepoPath%\%Application%\*.pyc /b /s') do (del %%a))
 +(FOR /f "delims=" %%a IN ('DIR %RepoPath%\%Application%\*.py /b /s') do (python-modernize -w %%a >> %LogFile%))
 +(FOR /f "delims=" %%a IN ('DIR %RepoPath%\%Application%\*.bak /b /s') do (del %%a))
 +</code>
  
  
Linea 586: Linea 1313:
   - [[https://www.geeksforgeeks.org/important-differences-between-python-2-x-and-python-3-x-with-examples/]]   - [[https://www.geeksforgeeks.org/important-differences-between-python-2-x-and-python-3-x-with-examples/]]
   - [[https://sebastianraschka.com/Articles/2014_python_2_3_key_diff.html]]   - [[https://sebastianraschka.com/Articles/2014_python_2_3_key_diff.html]]
 +  - [[https://python-modernize.readthedocs.io/en/latest/]]
  
  
python/porting_python_2_to_pyton_3.1579706362.txt.gz · Ultima modifica: 2020/01/22 15:19 da apressato
Torna su
CC Attribution-Share Alike 4.0 International
Driven by DokuWiki Recent changes RSS feed Valid CSS Valid XHTML 1.0