Fonctions
Une fonction regroupe des instructions que l’on peut appeler avec des valeurs d’entrée. Les paramètres nomment ces entrées dans la définition ; les arguments sont les valeurs fournies lors de l’appel. La fonction renvoie un résultat ou lève une exception. Ci-dessous, clamp ramène un nombre dans l’intervalle délimité par lower et upper : clamp(12, 0, 10) renvoie 10. Avec strict=True, une valeur hors de cet intervalle déclenche plutôt une exception. Les annotations comme value: float indiquent les types d’entrée attendus, et -> float le type de retour attendu ; elles ne vérifient pas ces types à l’exécution.
def clamp(value: float, lower: float, upper: float, *, strict: bool = False) -> float:
if lower > upper:
raise ValueError("lower must not exceed upper")
if strict and not lower <= value <= upper:
raise ValueError("value is outside the interval")
return min(max(value, lower), upper)
Le * rend les paramètres suivants nommés uniquement, ce qui convient aux indicateurs de comportement dont le sens serait obscur par position.
Types de paramètres
Python accepte des paramètres positionnels uniquement avant /, des paramètres positionnels ou nommés, des paramètres positionnels variadiques *args, des paramètres nommés uniquement après * et des paramètres nommés variadiques **kwargs. Utilisez l'interface la plus étroite qui communique l'intention ; transférer des arguments arbitraires réduit la facilité de découverte.
Les valeurs par défaut sont évaluées une fois
Les expressions par défaut s'exécutent à la définition de la fonction, pas à chaque appel. Évitez les valeurs mutables partagées :
def collect(item: str, bucket: list[str] | None = None) -> list[str]:
if bucket is None:
bucket = []
bucket.append(item)
return bucket
Retour et responsabilité
Atteindre la fin sans return renvoie None. Renvoyer plusieurs valeurs séparées par des virgules construit un tuple. Documentez si la fonction modifie un argument, renvoie un nouvel objet, effectue des E/S ou conserve des références.
Annotations et chaînes de documentation
Les annotations communiquent les types prévus aux lecteurs et aux outils ; l'interpréteur ne les impose généralement pas. Une chaîne de documentation concise doit expliquer le comportement, les invariants importants, les exceptions levées et les effets de bord surprenants plutôt que répéter la signature.
Règles de conception
- Séparez le calcul pur des E/S lorsque c'est pratique.
- Préférez des résultats explicites à l'affichage depuis une logique réutilisable.
- Levez des exceptions précises à la frontière où l'état invalide est reconnu.
- Maintenez une fonction à un niveau d'abstraction utile.
Portée locale et arguments partagés
Selon les règles de résolution des noms,
le code ordinaire d'une fonction cherche dans sa portée locale, les fonctions
englobantes, le module, puis les noms intégrés. Une affectation dans la fonction
rend normalement ce nom local dans tout son corps. Le lire avant cette affectation
lève UnboundLocalError, même si le module contient un nom identique. global
cible la liaison du module ; nonlocal, une liaison existante dans une fonction
englobante. Ces déclarations ne sont nécessaires ni pour lire un nom, ni pour
modifier une liste référencée.
def modify(items):
items.append(2) # modifier l'objet de l'appelant
items = [99] # relier seulement ce nom local
return items
numbers = [1]
assert modify(numbers) == [99]
assert numbers == [1, 2]
assert collect("a") == ["a"]
assert collect("b") == ["b"]
bucket = []
assert collect("c", bucket) is bucket
assert clamp(12, 0, 10) == 10
assert clamp(5, 0, 10, strict=True) == 5
clamp suppose des nombres finis et ordonnables ; ce n'est pas un validateur pour
NaN ou des objets quelconques. clamp(5, 0, 10, True) lève TypeError, car strict
exige un mot-clé. Un argument requis manquant, une liaison d'argument en double ou
un mot-clé inattendu lèvent aussi TypeError. Dans un appel, *values développe
les arguments positionnels et **options développe une association en arguments
nommés. def lie un objet fonction sans exécuter son corps ; une fonction peut
donc être passée comme valeur ou renvoyée par une autre fonction.