Débutant

Python 3.14 : annotations de type pour débutants

Découvrez les annotations de type en Python 3.14 : à quoi elles servent, comment les écrire et comment éviter les erreurs courantes.

Par Julien Mercier 7 min de lecture
Python 3.14 : annotations de type pour débutants

Les annotations de type, aussi appelées indications de type ou type hints, sont de plus en plus présentes dans les projets Python modernes. Pourtant, elles ne sont pas réservées aux développeurs expérimentés : elles peuvent aider dès les premiers programmes à rendre le code plus clair.

Le principe est simple : une annotation indique le type de valeur qu’une variable ou une fonction est censée utiliser. Par exemple, on peut préciser qu’un prénom est un texte, qu’un âge est un nombre entier ou qu’une fonction renvoie une liste.

Python reste un langage dynamique : écrire une annotation ne transforme pas Python en langage strict et ne déclenche pas automatiquement une erreur si vous donnez une valeur d’un autre type. Les annotations sont avant tout des informations utiles pour vous, pour les autres personnes qui lisent le code, pour l’éditeur et, si vous le souhaitez plus tard, pour des outils de vérification.

Dans ce guide, vous allez apprendre à les écrire progressivement avec Python 3.14, sans installer d’outil complexe et sans noyer vos premiers scripts sous des détails inutiles.

À quoi servent les annotations de type en Python ?

Dans un programme Python classique, le type d’une variable est déterminé par la valeur qu’elle contient. Vous pouvez donc écrire :

prenom = "Lina"
age = 28
prix = 19.99

Python comprend que prenom contient une chaîne de caractères, que age contient un entier et que prix contient un nombre décimal. Vous n’avez pas besoin de le déclarer à l’avance.

Avec une annotation, vous rendez cette intention visible directement dans le code :

prenom: str = "Lina"
age: int = 28
prix: float = 19.99

Les mots str, int et float décrivent respectivement une chaîne de caractères, un entier et un nombre décimal.

L’intérêt n’est pas de répéter inutilement ce que Python sait déjà. Les annotations deviennent utiles lorsque le programme grandit, quand une fonction accepte plusieurs paramètres ou lorsque vous revenez sur votre code quelques semaines plus tard.

Imaginez cette fonction :

def calculer_total(prix, quantite):
    return prix * quantite

Elle fonctionne, mais on ne sait pas immédiatement ce qui est attendu. prix doit-il être un nombre ? quantite peut-elle être un texte ? Que renvoie la fonction ? Une version annotée apporte ces réponses :

def calculer_total(prix: float, quantite: int) -> float:
    return prix * quantite

Le code indique ici que prix est prévu comme un nombre décimal, quantite comme un entier et que le résultat attendu est un nombre décimal.

Les annotations ont plusieurs bénéfices concrets :

  • elles rendent le rôle des variables et des paramètres plus facile à comprendre ;
  • elles améliorent l’aide affichée par des éditeurs comme Visual Studio Code ou PyCharm ;
  • elles facilitent la détection d’incohérences avec des outils spécialisés ;
  • elles servent de documentation directement à côté du code concerné ;
  • elles simplifient le travail en équipe, car les attentes d’une fonction sont plus explicites.

Pour un débutant, le premier bénéfice est souvent le plus important : relire son propre code devient moins difficile. Cela ne dispense pas de choisir des noms de variables clairs, mais c’est un complément très utile. Si les notions de variables vous semblent encore floues, commencez par notre guide sur les variables, types et conversions en Python.

Une annotation ne vérifie pas automatiquement votre programme

C’est le point essentiel à retenir : Python n’impose pas les annotations à l’exécution. Il les conserve comme des informations, mais ne les utilise pas automatiquement pour empêcher une mauvaise valeur.

Voici un exemple volontairement incohérent :

age: int = "vingt-huit"

print(age)

Ce programme peut s’exécuter et afficher vingt-huit. L’annotation int ne force pas la variable à contenir un entier.

De même, Python ne bloque pas nécessairement cet appel :

def afficher_age(age: int) -> None:
    print(f"Vous avez {age} ans.")

afficher_age("vingt-huit")

La fonction reçoit une chaîne alors que son annotation annonce un entier. Comme print() peut afficher une chaîne, aucune erreur ne survient ici. En revanche, si le code tente ensuite de faire un calcul, le problème peut apparaître.

def ajouter_un_an(age: int) -> int:
    return age + 1

ajouter_un_an("vingt-huit")

Dans ce cas, l’erreur vient de l’addition entre une chaîne et un entier, pas de l’annotation elle-même.

Pourquoi Python fonctionne-t-il ainsi ? Parce que les annotations sont conçues pour rester souples. Elles peuvent être lues par votre environnement de développement ou par des outils de contrôle statique, mais elles ne modifient pas le comportement normal de Python.

Par exemple, mypy est un outil qui peut analyser le code avant son exécution et signaler des incompatibilités de types. ty, développé par Astral, est un autre vérificateur de types pour Python. Vous n’avez toutefois pas besoin de les utiliser pour commencer à annoter vos fonctions.

Une annotation décrit une intention. Une validation, elle, vérifie réellement une valeur au moment où le programme s’exécute. Ce sont deux mécanismes différents.

Lorsqu’une valeur vient d’un utilisateur, d’un fichier ou d’une API, vous devez donc toujours la contrôler ou la convertir si nécessaire. Le cas classique est input() : cette fonction renvoie toujours du texte. Consultez aussi notre article sur la saisie et la conversion de valeurs avec input().

Annoter simplement une variable

La forme la plus simple est la suivante :

nom_variable: type = valeur

Voici quelques exemples réalistes :

titre: str = "Apprendre Python"
nombre_lecons: int = 12
progression: float = 75.5
formation_terminee: bool = False

Vous pouvez aussi annoter une variable sans lui donner de valeur immédiatement :

message: str
message = "Bonjour"

Cette écriture est surtout utile quand la valeur est attribuée plus loin dans le programme. Pour vos premiers scripts, déclarer et initialiser la variable sur la même ligne reste souvent plus lisible.

Les annotations de variables sont intéressantes lorsqu’un nom seul ne suffit pas à décrire clairement la donnée. Dans cet exemple, elles servent aussi de mémo :

ville: str = "Nantes"
temperature: float = 18.5
nombre_habitants: int = 325070

Il ne faut pas pour autant annoter chaque valeur de manière mécanique dans un fichier très court. Cette version est déjà parfaitement compréhensible sans annotations :

bonjour = "Bonjour"
compteur = 0

Utilisez-les quand elles apportent une information utile, notamment dans les fonctions, les projets en plusieurs fichiers ou les structures de données moins évidentes.

Annoter les paramètres et la valeur de retour d’une fonction

Les fonctions sont l’endroit où les annotations deviennent le plus utiles. Leur syntaxe comporte deux parties :

  • le type attendu après le nom de chaque paramètre ;
  • le type de la valeur renvoyée après la parenthèse fermante, précédé de ->.

La structure générale est la suivante :

def nom_fonction(parametre: type) -> type_retour:
    # instructions
    return valeur

Reprenons une fonction très simple :

def saluer(prenom: str) -> str:
    return f"Bonjour {prenom} !"

Cette fonction attend un prénom sous forme de texte et renvoie également un texte. Elle peut être appelée ainsi :

message = saluer("Samir")
print(message)

Avec deux paramètres de types différents :

def calculer_prix_ttc(prix_ht: float, taux_tva: float) -> float:
    return prix_ht * (1 + taux_tva)

Pour un prix hors taxes de 100.0 et un taux de 0.20, le résultat est 120.0.

total = calculer_prix_ttc(100.0, 0.20)
print(total)

Une fonction qui ne renvoie pas de résultat utile doit être annotée avec None. C’est notamment le cas d’une fonction qui affiche simplement un message :

def afficher_bienvenue(prenom: str) -> None:
    print(f"Bienvenue, {prenom} !")

None signifie ici que la fonction ne retourne pas de valeur exploitable. Elle réalise une action : l’affichage à l’écran.

Ce point est lié à la différence entre print() et return. print() montre une information dans la console ; return transmet une valeur à l’endroit où la fonction a été appelée. Vous pouvez revoir les bases dans notre article consacré à la définition, l’appel et les paramètres des fonctions Python.

Les types essentiels à connaître : str, int, float, bool et None

Avant de chercher des annotations avancées, maîtrisez les types intégrés les plus fréquents. Ils correspondent aux valeurs que vous utilisez déjà dans vos programmes.

str pour le texte

str signifie string, c’est-à-dire une chaîne de caractères. Les prénoms, adresses e-mail, phrases et codes saisis comme texte sont généralement des str.

def mettre_en_majuscule(texte: str) -> str:
    return texte.upper()

Découvrez davantage de manipulations utiles dans notre guide des chaînes de caractères en Python.

int et float pour les nombres

int désigne un entier, comme 3, 0 ou -12. float désigne un nombre à virgule flottante, généralement écrit avec un point en Python, comme 3.14 ou 19.99.

def doubler(nombre: int) -> int:
    return nombre * 2

def appliquer_reduction(prix: float, reduction: float) -> float:
    return prix * (1 - reduction)

Dans le second exemple, reduction représente une proportion : 0.15 correspond à 15 %. Pour mieux comprendre les calculs et les conversions, consultez notre article sur les entiers, décimaux et arrondis en Python.

bool pour vrai ou faux

Le type bool ne contient que deux valeurs : True et False. Il est courant pour représenter un état ou le résultat d’un test.

def est_majeur(age: int) -> bool:
    return age >= 18

Cette fonction renvoie True si l’âge est au moins égal à 18, sinon False. Les booléens sont au cœur des conditions if, expliquées dans notre guide sur if, elif et else en Python.

None pour l’absence de valeur

None est une valeur spéciale qui représente l’absence de valeur. On l’utilise souvent pour signaler qu’une information n’est pas encore connue, ou pour annoter une fonction qui ne renvoie rien.

def rechercher_email(utilisateur: str) -> str | None:
    if utilisateur == "lina":
        return "[email protected]"

    return None

Le résultat peut être une chaîne ou None. L’écriture str | None est disponible dans les versions récentes de Python et reste très lisible : « une chaîne de caractères ou aucune valeur ».

Annoter les listes et les dictionnaires

Les listes et les dictionnaires contiennent d’autres valeurs. Il est donc utile de préciser non seulement la structure, mais aussi le type des éléments stockés.

Avec Python 3.14, vous pouvez utiliser directement les types intégrés list et dict entre crochets.

Une liste de prénoms :

prenoms: list[str] = ["Lina", "Noah", "Inès"]

Une liste de nombres entiers :

notes: list[int] = [12, 15, 18]

Une fonction qui calcule une moyenne peut donc annoncer qu’elle attend une liste d’entiers et renvoie un nombre décimal :

def calculer_moyenne(notes: list[int]) -> float:
    return sum(notes) / len(notes)

Attention : cette fonction suppose que la liste contient au moins une note. Avec une liste vide, une division par zéro se produirait. Une annotation améliore la clarté, mais elle ne remplace pas la gestion des cas particuliers.

Pour un dictionnaire, vous indiquez le type des clés, puis celui des valeurs :

profil: dict[str, str] = {
    "prenom": "Lina",
    "ville": "Nantes"
}

Ici, les clés et les valeurs sont toutes des chaînes. Pour un dictionnaire d’articles avec des quantités entières :

stock: dict[str, int] = {
    "cahier": 24,
    "stylo": 50
}

Dans les projets débutants, il est fréquent qu’un dictionnaire mélange plusieurs types de valeurs :

utilisateur = {
    "prenom": "Lina",
    "age": 28,
    "actif": True
}

Il est possible de décrire ce genre de structure plus précisément, mais cela introduit des notions supplémentaires. Au début, privilégiez soit une annotation générale comme dict, soit une structure plus simple et homogène lorsque c’est possible. Notre article sur les dictionnaires Python et les couples clé-valeur vous aidera à consolider les bases.

Ce qui est important avec Python 3.14

Python 3.14 poursuit l’évolution des annotations de type sans modifier la syntaxe de base que vous venez de voir. Les écritures suivantes sont naturelles et recommandées dans du code récent :

def ajouter_article(panier: list[str], article: str) -> list[str]:
    panier.append(article)
    return panier

Vous n’avez pas besoin d’importer List ou Dict depuis le module typing pour écrire list[str] ou dict[str, int]. Les types intégrés peuvent être paramétrés directement dans les versions modernes de Python.

Python 3.14 apporte aussi un changement technique important dans la manière dont les annotations sont évaluées : leur évaluation est différée. En pratique, les débutants peuvent surtout retenir deux choses :

  • vous pouvez écrire des annotations simples sans vous préoccuper du fonctionnement interne de Python ;
  • les bibliothèques et outils qui inspectent les annotations disposent d’outils adaptés dans le module annotationlib.

Ce changement concerne principalement les auteurs de bibliothèques, les frameworks et les outils d’analyse qui lisent les annotations à l’exécution. Dans un script d’apprentissage, vous n’avez généralement rien de spécial à faire.

La documentation officielle propose une référence complète sur les annotations et le module typing. Elle est précieuse lorsque vous aurez besoin de types plus avancés, mais elle n’est pas nécessaire pour écrire vos premières fonctions annotées.

Les erreurs courantes à éviter

Les annotations restent simples à utiliser si vous évitez quelques confusions fréquentes.

Confondre un type avec une chaîne de caractères

Écrivez le type sans guillemets dans les cas ordinaires :

age: int = 28
prenom: str = "Lina"

Évitez :

age: "int" = 28

Dans certains cas avancés, des annotations sous forme de texte peuvent avoir un usage, notamment pour référencer un type défini plus loin. Mais ce n’est pas nécessaire dans les exemples débutants.

Utiliser une annotation à la place d’une conversion

Ce code n’est pas correct si vous voulez réellement obtenir un entier :

age: int = input("Votre âge : ")

input() renvoie du texte. L’annotation dit seulement que vous souhaitiez un entier ; elle ne convertit pas la réponse. Il faut utiliser int() :

age: int = int(input("Votre âge : "))

Oublier None lorsqu’une valeur peut manquer

Si une fonction peut ne rien trouver, annoncer uniquement str est trompeur. Préférez :

def trouver_code(nom: str) -> str | None:
    return None

Cette annotation incite aussi la personne qui appelle la fonction à prévoir le cas où le résultat vaut None.

Ajouter des annotations trop complexes trop tôt

Une annotation doit améliorer la lecture. Si vous passez plus de temps à décrire les types qu’à comprendre votre programme, revenez à des types simples : str, int, float, bool, list, dict et None.

Il vaut mieux une fonction courte, bien nommée et correctement annotée qu’une fonction difficile à lire avec une annotation très élaborée.

Une bonne méthode pour commencer sans se compliquer

Vous n’avez pas à convertir tout votre ancien code d’un coup. Adoptez les annotations petit à petit, là où elles ont le plus de valeur.

  • Commencez par annoter les paramètres et le retour de vos nouvelles fonctions.
  • Ajoutez des annotations aux listes et dictionnaires lorsque leur contenu est homogène.
  • Utilisez str | None lorsqu’une fonction peut ne pas produire de résultat.
  • Continuez à convertir et vérifier les données entrantes, même lorsqu’elles sont annotées.
  • Activez éventuellement les vérifications de votre éditeur plus tard, quand vous serez à l’aise avec les bases.

Voici un petit exemple qui rassemble les notions principales :

def ajouter_note(notes: list[int], note: int) -> None:
    notes.append(note)

def calculer_moyenne(notes: list[int]) -> float | None:
    if len(notes) == 0:
        return None

    return sum(notes) / len(notes)

notes_eleve: list[int] = [14, 16]
ajouter_note(notes_eleve, 18)

moyenne = calculer_moyenne(notes_eleve)

if moyenne is not None:
    print(f"Moyenne : {moyenne}")

Le programme indique clairement ce qu’il manipule : une liste d’entiers pour les notes, une note entière ajoutée à la liste, et une moyenne qui peut être un nombre décimal ou None si la liste est vide.

Conclusion : des repères utiles pour vos futurs projets

Les annotations de type ne rendent pas Python plus compliqué : bien employées, elles rendent surtout votre intention plus visible. Retenez qu’elles ne vérifient pas automatiquement les valeurs, mais qu’elles aident à documenter les fonctions, à mieux utiliser votre éditeur et à préparer des projets plus structurés.

Avec Python 3.14, commencez simplement par annoter vos paramètres, vos valeurs de retour et les listes ou dictionnaires les plus évidents. Intégrez cette habitude dans votre prochain mini-projet : votre code sera plus facile à relire, à corriger et à faire évoluer.

Commentaires· Aucun commentaire pour l'instant

Soyez le premier à réagir.

Laisser un commentaire