En Python les valeurs des arguments par défaut sont définis à la création de la fonction, et non à l’appel, et c’est parfois bien :
SENTINEL = object()
def work(arg=SENTINEL):
if arg is SENTINEL:
print("No argument has been given.")
else:
print("Argument has been given and is:", arg)
De cette manière si on passe None
, qui pourrait être une valeur légitime dans un certain contexte, alors on est toujours capable de savoir si l’utilisateur n’a rien donné, ou s’il a donné None
, par exemple.
Mais c’est parfois surprenant, et on s’est tous fait mordre en mettant une valeur modifiable en argument par défaut…
La PEP 671 propose une syntaxe pour indiquer qu’une valeur (d’un argument par défaut) doit être construite à chaque appel, plutôt qu’une fois pour toutes à la définition de la fonction.
Ça économisera beaucoup de :
if the_arg is None:
the_arg = its_default_mutable_value
et en plus d’économiser des lignes, ça rendra les prototypes plus vrais: au lieu de voir None
on verra la bonne valeur dans le prototype de la fonction, c’est toujours sympa.
Et en dehors du côté verbeux et des deux lignes économisées, ça pourrait même être utilisé dans tout un tat d’autres contextes, l’exemple typique dans la lib bisect:
def bisect(a, x, lo=0, hi=None):
hi
ne vaut pas vraiment None
par défaut, mais len(a)
, c’est tentant de chercher une syntaxe pour exprimer ça, comme (mais attention c’est pas ça) :
def bisect(a, x, lo=0, hi=len(a)):
Le jeu : essayez de deviner quelle syntaxe pourrait convenir avant de lire la PEP