Vue d'ensemble
Python 3.0, publié le 3 décembre 2008, est une version historique du langage. Surnommée "Python 3000" ou "Py3k", cette version rompt délibérément la compatibilité avec la branche 2.x afin de corriger des défauts de conception accumulés depuis les débuts du langage.
L'objectif était ambitieux : nettoyer le langage en supprimant les redondances, en unifiant les types et en modernisant la syntaxe. Cette décision courageuse a provoqué une longue période de transition durant laquelle les deux branches ont coexisté, mais elle a permis de poser les bases du Python moderne que nous utilisons aujourd'hui.
Nouveautés majeures
print() devient une fonction
Le changement le plus emblématique de Python 3.0 est la transformation de print d'une instruction en une fonction. Ce choix permet d'utiliser print() comme n'importe quelle autre fonction : on peut la passer en argument, la remplacer, et surtout profiter de paramètres nommés comme sep, end et file.
# Python 2 : print est une instruction
# print "Bonjour", "le", "monde"
# Python 3 : print est une fonction
print("Bonjour", "le", "monde")
# Bonjour le monde
# Le paramètre sep contrôle le séparateur
coordonnees = [48.8566, 2.3522]
print("Latitude", coordonnees[0], sep=" : ")
# Latitude : 48.8566
# Le paramètre end évite le retour à la ligne
for fruit in ["pomme", "poire", "banane"]:
print(fruit, end=" | ")
# pomme | poire | banane |
# Le paramètre file redirige la sortie
with open("journal.log", "w") as f:
print("Démarrage du traitement", file=f)
print("Traitement terminé", file=f)
Chaînes Unicode par défaut
En Python 3.0, toutes les chaînes de caractères sont désormais en Unicode (type str). Le type bytes représente explicitement les données binaires. Cette séparation claire entre texte et données binaires élimine toute une catégorie de bugs liés à l'encodage.
# Les chaînes sont nativement Unicode
message = "Café crème et crêpe au chocolat"
print(message) # Café crème et crêpe au chocolat
print(len(message)) # 31 (chaque caractère compte pour 1)
# Distinction claire entre texte et octets
texte = "Résumé"
octets = texte.encode("utf-8")
print(type(texte)) # <class 'str'>
print(type(octets)) # <class 'bytes'>
print(octets) # b'R\xc3\xa9sum\xc3\xa9'
# Conversion inverse
texte_retrouve = octets.decode("utf-8")
print(texte_retrouve) # Résumé
# On ne peut plus mélanger texte et octets
# texte + octets # TypeError!
Division entière
En Python 2, la division entre deux entiers renvoyait un entier (division entière). En Python 3.0, l'opérateur / effectue toujours une division réelle, tandis que // effectue la division entière. Ce changement élimine une source fréquente d'erreurs, notamment dans les calculs scientifiques.
# Python 2 : 7 / 2 donnait 3
# Python 3 : 7 / 2 donne 3.5
# Division réelle (toujours un flottant)
resultat = 7 / 2
print(resultat) # 3.5
# Division entière (troncature)
resultat_entier = 7 // 2
print(resultat_entier) # 3
# Exemple pratique : calcul de moyenne
notes = [14, 17, 12, 15, 18]
moyenne = sum(notes) / len(notes)
print(f"Moyenne : {moyenne}") # Moyenne : 15.2
# Exemple pratique : répartition en groupes
eleves = 37
groupes = 5
par_groupe = eleves // groupes
reste = eleves % groupes
print(f"{par_groupe} par groupe, {reste} restant(s)")
# 7 par groupe, 2 restant(s)
Nouvelle syntaxe des exceptions
Python 3.0 remplace la syntaxe except Exception, e par except Exception as e. Cette nouvelle forme est plus lisible et cohérente avec le reste du langage. Elle permet également de capturer plusieurs types d'exceptions sans ambiguïté.
# Python 2 : except ValueError, e:
# Python 3 : except ValueError as e:
def convertir_en_entier(valeur):
"""Convertit une valeur en entier avec gestion d'erreur."""
try:
return int(valeur)
except ValueError as erreur:
print(f"Conversion impossible : {erreur}")
return None
# Capture de plusieurs types d'exceptions
def lire_configuration(chemin):
"""Lit un fichier de configuration avec gestion robuste."""
try:
with open(chemin) as f:
return f.read()
except FileNotFoundError as e:
print(f"Fichier introuvable : {e.filename}")
except PermissionError as e:
print(f"Permission refusée : {e}")
except OSError as e:
print(f"Erreur système : {e}")
return None
print(convertir_en_entier("42")) # 42
print(convertir_en_entier("abc")) # Conversion impossible : ...
# None
Améliorations mineures
dict.keys(),dict.values()etdict.items()renvoient désormais des vues (views) au lieu de listes.map()etfilter()renvoient des itérateurs au lieu de listes.range()remplacexrange()et renvoie un objet séquence efficace.- Suppression de
raw_input():input()le remplace. - Les comparaisons entre types incompatibles lèvent une exception au lieu de renvoyer un résultat arbitraire.
- Les littéraux octaux utilisent le préfixe
0o(ex :0o777au lieu de0777).
Dépréciations et suppressions
Python 3.0 supprime de nombreux éléments obsolètes :
- Les classes « old-style » disparaissent : toutes les classes héritent désormais de
object. - Les types
longetintsont fusionnés en un seul typeint. - Le mot-clé
execdevient une fonction. - Les backticks (
`x`) pour la représentation sont supprimés au profit derepr(x). - Le module
stringperd ses fonctions dépréciées (string.join,string.find, etc.). - L'instruction
raise Exception, "message"est remplacée parraise Exception("message").
