Différences entre Python 2.x et 3.x

Python 3.0, souvent appelé Python 3000, ou simplement Py3k, est une mise à niveau majeure par rapport aux versions antérieures de Python.

Afin de ne pas apporter trop de bagage, Python 3.0 a été conçu sans tenir compte de la rétrocompatibilité.

De nombreux programmes conçus pour les versions antérieures de Python ne peuvent pas fonctionner correctement sur Python 3.0.

Pour accompagner les programmes existants, Python 2.6 sert de version de transition, en utilisant essentiellement la syntaxe et les bibliothèques de Python 2.x, tout en envisageant également la migration vers Python 3.0, ce qui permet d'utiliser certaines syntaxes et fonctions de Python 3.0.

Pour les nouveaux programmes Python, il est recommandé d'utiliser la syntaxe de Python 3.0.

Sauf si l'environnement d'exécution ne peut pas installer Python 3.0, ou si le programme lui-même utilise des bibliothèques tierces qui ne prennent pas en charge Python 3.0. Actuellement, les bibliothèques tierces qui ne prennent pas en charge Python 3.0 incluent Twisted, py2exe, PIL, etc.

La plupart des bibliothèques tierces s'efforcent d'être compatibles avec Python 3.0. Même si vous ne pouvez pas utiliser Python 3.0 immédiatement, il est recommandé d'écrire des programmes compatibles avec Python 3.0, puis de les exécuter avec Python 2.6 ou Python 2.7.

Les changements dans Python 3.0 portent principalement sur les aspects suivants :


fonction print

L'instruction print a disparu, remplacée par la fonctionprint(). Python 2.6 et Python 2.7 prennent partiellement en charge cette forme de syntaxe print. Dans Python 2.6 et Python 2.7, les trois formes suivantes sont équivalentes :

print "fish"
print ("fish") # 注意print后面有个空格
print("fish") # print()不能带有任何其它参数

Cependant, Python 2.6 prend déjà en charge la nouvelle syntaxe print(), par exemple :

from __future__ import print_function
print("fish", "panda", sep=', ')

Si vous souhaitez utiliser la fonction print de Python 3.x dans Python 2.x, vous pouvez importer le paquet__future__, ce qui désactive l'instruction print de Python 2.x et adopte la fonction print de Python 3.x :

Exemple

>>> liste =["a", "b", "c"]
>>> print list    # instruction print de python2.x
['a', 'b', 'c']
>>> from __future__ import print_function  # Importer le paquet __future__
>>> print list     # L'instruction print de Python2.x est désactivée, son utilisation provoque une erreur
  Fichier "<stdin>", ligne 1
    print list
             ^
SyntaxError: syntaxe invalide
>>> print (list)   # Utiliser la fonction print de Python3.x
['a', 'b', 'c']
>>>

De nombreuses fonctionnalités de compatibilité entre Python3.x et Python2.x peuvent être importées via__future__ce paquet.


Unicode

Python 2 a un type str() ASCII, et unicode() est distinct, pas un type d'octet.

Maintenant, dans Python 3, nous avons enfin des chaînes Unicode (utf-8), et une classe d'octets : bytes et bytearrays.

Comme les fichiers source Python3.x utilisent l'encodage utf-8 par défaut, utiliser le chinois est plus pratique :

>>> 中国 = 'china' 
>>>print(中国) 
china

Python 2.x

>>> str = "我爱北京天安门"
>>> str
'\xe6\x88\x91\xe7\x88\xb1\xe5\x8c\x97\xe4\xba\xac\xe5\xa4\xa9\xe5\xae\x89\xe9\x97\xa8'
>>> str = u"我爱北京天安门"
>>> str
u'\u6211\u7231\u5317\u4eac\u5929\u5b89\u95e8'

Python 3.x

>>> str = "我爱北京天安门"
>>> str
'我爱北京天安门'

Opération de division

La division en Python semble très sophistiquée par rapport à d'autres langages, avec un ensemble complexe de règles. Il y a deux opérateurs de division en Python :/et//

D'abord, parlons de la/division :

Dans Python 2.x,/la division est comme dans la plupart des langages que nous connaissons, tels que Java et C : la division entière donne un entier, en ignorant complètement la partie fractionnaire, tandis que la division flottante conserve la partie décimale et donne un résultat flottant.

Dans Python 3.x,/la division ne fait plus cela ; le résultat de la division d'entiers est aussi un flottant.

Python 2.x :

>>> 1 / 2
0
>>> 1.0 / 2.0
0.5

Python 3.x:

>>> 1/2
0.5

Quant à//la division, ce type de division est appelé division plancher. Elle effectue automatiquement une opération plancher sur le résultat de la division, et elle est cohérente dans Python 2.x et Python 3.x.

python 2.x:

>>> -1 // 2
-1

python 3.x:

>>> -1 // 2
-1

Notez qu'elle ne supprime pas la partie fractionnaire, mais effectue une opération plancher. Si vous souhaitez tronquer la partie entière, vous devez utiliser la fonction trunc du module math.

python 3.x:

>>> import math
>>> math.trunc(1 / 2)
0
>>> math.trunc(-1 / 2)
0

Exceptions

La gestion des exceptions a également légèrement changé dans Python 3. Dans Python 3, nous utilisons désormais 'as' comme mot-clé.

La syntaxe de capture des exceptions est passée deexcept exc, varàexcept exc as var。

L'utilisation de la syntaxe 'except (exc1, exc2) as var' permet de capturer plusieurs types d'exceptions en même temps. Python 2.6 prend déjà en charge les deux syntaxes.

  • 1. À l'époque de la 2.x, tous les types d'objets pouvaient être levés directement. À l'époque de la 3.x, seuls les objets dérivés de BaseException peuvent être levés.
  • 2. En 2.x, l'instruction raise utilisait une virgule pour séparer le type d'objet levé et l'argument. La 3.x a supprimé cette syntaxe étrange ; vous pouvez simplement appeler le constructeur pour lever un objet.

À l'époque de la 2.x, outre l'indication d'erreurs de programme, les exceptions étaient souvent utilisées pour des choses que les structures de contrôle ordinaires devraient faire. En 3.x, vous pouvez voir que les concepteurs ont rendu les exceptions plus spécifiques ; les instructions de gestion des exceptions ne devraient être utilisées que lorsque des erreurs se produisent.

Python 2.xLa syntaxe de gestion des exceptions utilise une virgule.

try:
    # code
except Exception, e:
    print e

Python 3.xLa syntaxe de gestion des exceptions utilise 'as'.

try:
    # code
except Exception as e:
    print(e)

xrange() et range()

Python 2.xrange() renvoie une liste, tandis que xrange() renvoie un générateur (plus économe en mémoire).

range(5)  # 返回 [0, 1, 2, 3, 4]
xrange(5)  # 返回 xrange 对象,按需生成数字

Python 3.xxrange() a été supprimé, et range() renvoie un générateur, ce qui économise de la mémoire.

range(5)  # 返回一个迭代器,按需生成数字

Représentation des littéraux octaux

Les nombres octaux doivent être écrits sous la forme 0o777 ; l'ancienne forme 0777 ne peut plus être utilisée ; le binaire doit être écrit sous la forme0b111。

Ajout d'unebin()fonction pour convertir un entier en chaîne binaire. Python 2.6 prend déjà en charge les deux syntaxes.

Dans Python 3.x, il n'existe qu'une seule façon de représenter un littéral octal, à savoir 0o1000.

python 2.x

>>> 0o1000
512
>>> 01000
512

python 3.x

>>> 01000
  File "<stdin>", line 1
    01000
        ^
SyntaxError: invalid token
>>> 0o1000
512

Opérateurs d'inégalité

Dans Python 2.x, il y a deux façons d'écrire « différent de » : != et <>

Dans Python 3.x, <> a été supprimé, ne laissant que !=. Heureusement, je n'ai jamais pris l'habitude d'utiliser <>.


Suppression de l'expression repr ``

Dans Python 2.x, les backticks `` sont équivalents à la fonction repr.

Python 3.x a supprimé la syntaxe `` et n'autorise que la fonction repr. Est-ce pour rendre le code plus clair ? Cependant, j'ai l'impression que l'occasion d'utiliser repr est rare ; je ne l'utilise généralement que pour le débogage. La plupart du temps, j'utilise la fonction str pour décrire les objets sous forme de chaînes.

def sendMail(from_: str, to: str, title: str, body: str) -> bool:
    pass

Plusieurs modules ont été renommés (conformément à PEP8)

Anciens noms Nouveaux noms
_winreg winreg
ConfigParser configparser
copy_reg copyreg
File queue
SocketServer socketserver
repr reprlib

Le module StringIO est désormais fusionné dans le nouveau module io. Les modules tels que new, md5, gopherlib ont été supprimés. Python 2.6 prend déjà en charge le nouveau module io.

httplib, BaseHTTPServer, CGIHTTPServer, SimpleHTTPServer, Cookie et cookielib ont été fusionnés dans le paquet http.

L'instruction exec a été supprimée, ne laissant que la fonction exec(). Python 2.6 prend déjà en charge la fonction exec().


5. Types de données

1) Py3.X a supprimé le type long. Désormais, il n'existe qu'un seul type entier — int, mais son comportement est semblable à celui du type long en 2.X.

2) Un nouveau type bytes a été ajouté, correspondant à la chaîne de 8 bits en 2.X. Pour définir un littéral bytes :

>>> b = b'china' 
>>> type(b) 
<type 'bytes'> 

Les objets str et bytes peuvent utiliser les méthodes .encode() (str -> bytes) ou .decode() (bytes -> str) pour se convertir mutuellement.

>>> s = b.decode() 
>>> s 
'china' 
>>> b1 = s.encode() 
>>> b1 
b'china' 

3) Les méthodes de dict .keys(), .items() et .values() renvoient des itérateurs, tandis que les anciennes fonctions telles que iterkeys() sont obsolètes. dict.has_key() a également été supprimé ; utilisez 'in' à la place.


6. Réorganisation de la bibliothèque standard

Python 3.x : certains modules ont été réorganisés ou renommés. Par exemple, urllib et urlparse ont été fusionnés dans urllib.

# Python 2.x
import urllib
import urlparse

# Python 3.x
import urllib.parse

7. Les fonctions iteritems() et items()

Python 2.x: les dictionnaires ont les méthodes items() et iteritems() ; items() renvoie une liste, iteritems() renvoie un itérateur.

d = {'a': 1, 'b': 2}
d.items()     # 返回 [('a', 1), ('b', 2)]
d.iteritems()  # 返回字典的迭代器

Python 3.x: iteritems() a été supprimé, et items() renvoie une vue de dictionnaire (c'est-à-dire un itérateur).

d = {'a': 1, 'b': 2}
d.items()     # 返回 dict_items([('a', 1), ('b', 2)])

8. Prise en charge du module __future__

Python 3.x : de nombreuses fonctionnalités de Python 2.x ont été supprimées. Les utilisateurs de Python 2.x qui souhaitent utiliser le comportement de Python 3.x à l'avance dans leur code peuvent utiliser les imports __future__ pour assurer la compatibilité.

from __future__ import print_function

9. Tri des dictionnaires

Python 2.x : les dictionnaires ne sont pas ordonnés (aucun ordre garanti).

Python 3.x : les dictionnaires sont ordonnés, préservant les éléments dans l'ordre d'insertion.

10. méthode next()

Python 2.x: next() est une fonction, généralement utilisée avec iter().

Python 3.x: next() est une fonction intégrée, utilisée de la même manière qu'en Python 2.x, mais ses paramètres sont différents. Dans Python 3.x, une valeur par défaut peut être définie via next(iterator, default).

Autres extensions