Une fonction en python aura cette forme ci
Copier le code
1 2 def add(a, b): return a + b
Si on part de cette fonction tout simple d'addition on se rend vite compte de ses limites. Elle ne peux pas prendre plusieurs paramètres. Pour faire cela on est obligé de modifier la signature de la fonction
Copier le code
1 2 def add(a, b, c): return a + b + c
C'est une solution pas très dynamique.
Nous allons donc voir comment faire cela tout en ayant un code python souple
Les paramètres positionnels
On les voit souvent comme *args dans la littérature même si ce n'est qu'une convention. On peut leur donner le nom que vous préférez (même si je vous conseille fortement de respecter la convention), il faut juste conserver le *
Ce caractère n'est pas un pointeur, c'est une déstructuration de liste que l'on nomme unpack
Copier le code
1 2 3 4 5 >>> a = [1, 2, 3] >>> print(*a) 1 2 3 >>> print(a) [1, 2, 3]
Dans cet exemple il prend les valeurs de cette liste pour les passer en paramètre de la fonction print()
D'ailleurs si on regarde la doc de cette fonction on se rend compte qu'elle est compatible avec l'unpacking de liste
Copier le code
1 2 3 4 5 >>> help(print) Help on built-in function print in module builtins: print(*args, sep=' ', end='\n', file=None, flush=False) ...
On va appliquer ce concept sur notre fonction d'addition
Copier le code
1 2 3 4 5 6 7 >>> def add(*args): ... print(args) ... >>> add(1, 2) (1, 2) >>> add(1, 2, 3) (1, 2, 3)
On se rend compte que notre fonction s'adapte à ces paramètres sans se crasher (je n'ai pas implémenté la logique d'addition mais vous avez compris le concept)
Les paramètres nommés
On voit également **kwargs dans la littérature même si ce n'est qu'une convention. On peut leur donner le nom que vous préférez (même si je vous conseille fortement de respecter la convention), il faut juste conserver le **
C'est une déstructuration de dictionnaire que l'on nomme unpack
On garde le même principe que sur les paramètres positionnels mais cette fois sur notre fonction on doit nommer le nom du paramètre
Copier le code
1 2 3 4 5 6 7 >>> def add(**kwargs): ... print(kwargs) ... >>> add(a=1, b=2) {'a': 1, 'b': 2} >>> add(a=1, b=2, c=3) {'a': 1, 'b': 2, 'c': 3}
Et les deux
On peut évidemment combiner les 2 types de paramètres, mais on doit impérativement les mettre dans un ordre précis. Les paramètres positionnels et ensuite les paramètres nommés
Copier le code
1 2 3 4 5 6 7 8 9 10 >>> def add(*args, **kwargs): ... print(args, kwargs) ... >>> add(0, a=1, b=2) (0,) {'a': 1, 'b': 2} >>> add(a=0, 1) File "<python-input-12>", line 1 add(a=0, 1) ^ SyntaxError: positional argument follows keyword argument
C'est une solution très souple lorsqu'on ne connaît pas à l'avance les paramètres de la fonction.
Mais attention à l'utiliser en cas d'absolue nécessité, car cela alourdit le code. On ne peut pas, au 1er coup d'œil, voir ce qu'attend la fonction : on doit aller regarder son contenu et lire attentivement la documentation.
D'ailleurs si vous l'utilisez mettez une docstring avec des exemples