Python Language Définir une fonction avec un nombre arbitraire d'arguments


Exemple

Nombre arbitraire d'arguments de position:

Définir une fonction capable de prendre un nombre arbitraire d’arguments peut être fait en préfixant l’un des arguments avec un *

def func(*args):
    # args will be a tuple containing all values that are passed in
    for i in args:
        print(i)

func(1, 2, 3)  # Calling it with 3 arguments
# Out: 1
#      2
#      3

list_of_arg_values = [1, 2, 3]
func(*list_of_arg_values)  # Calling it with list of values, * expands the list
# Out: 1
#      2
#      3 

func()  # Calling it without arguments
# No Output 

Vous ne pouvez pas fournir une valeur par défaut pour args , par exemple func(*args=[1, 2, 3]) générera une erreur de syntaxe (ne compilera même pas).

Vous ne pouvez pas les fournir par nom lorsque vous appelez la fonction, par exemple func(*args=[1, 2, 3]) TypeError une TypeError .

Mais si vous avez déjà vos arguments dans un tableau (ou tout autre Iterable ), vous pouvez appeler votre fonction comme ceci: func(*my_stuff) .

Ces arguments ( *args ) sont accessibles par index, par exemple args[0] renverra le premier argument

Nombre arbitraire d'arguments de mot clé

Vous pouvez prendre un nombre arbitraire d'arguments avec un nom en définissant un argument dans la définition avec deux * devant lui:

def func(**kwargs):
    # kwargs will be a dictionary containing the names as keys and the values as values
    for name, value in kwargs.items():
        print(name, value)

func(value1=1, value2=2, value3=3)   # Calling it with 3 arguments
# Out: value1 1
#      value2 2
#      value3 3

func()                               # Calling it without arguments
# No Out put

my_dict = {'foo': 1, 'bar': 2}
func(**my_dict)                      # Calling it with a dictionary
# Out: foo 1
#      bar 2

Vous ne pouvez pas les fournir sans noms, par exemple func(1, 2, 3) va générer une TypeError .

kwargs est un dictionnaire python natif. Par exemple, args['value1'] donnera la valeur de l'argument value1 . Assurez-vous de vérifier au préalable qu'il existe un tel argument ou qu'une KeyError sera KeyError .

Attention

Vous pouvez les mélanger avec d'autres arguments facultatifs et obligatoires, mais l'ordre dans la définition est important.

Les arguments position / mot-clé viennent en premier. (Arguments requis).
Puis viennent les arguments arbitraires *arg . (Optionnel).
Ensuite, les arguments contenant uniquement des mots clés viennent ensuite. (Champs obligatoires).
Enfin, le mot-clé arbitraire **kwargs vient. (Optionnel).

#       |-positional-|-optional-|---keyword-only--|-optional-|
def func(arg1, arg2=10 , *args, kwarg1, kwarg2=2, **kwargs):
     pass
  • arg1 doit être donné, sinon une TypeError est TypeError . Il peut être donné comme positionnel ( func(10) ) ou mot-clé argument ( func(arg1=10) ).
  • kwarg1 doit également être donné, mais il ne peut être fourni qu'en tant que mot-clé: func(kwarg1=10) .
  • arg2 et kwarg2 sont optionnels. Si la valeur doit être modifiée, les mêmes règles que pour arg1 (positionnelle ou mot clé) et kwarg1 (uniquement mot clé) s'appliquent.
  • *args intercepte des paramètres de position supplémentaires. Mais notez que arg1 et arg2 doivent être fournis comme arguments positionnels pour passer des arguments à *args : func(1, 1, 1, 1) .
  • **kwargs attrape tous les paramètres de mots-clés supplémentaires. Dans ce cas, tout paramètre qui n’est pas arg1 , arg2 , kwarg1 ou kwarg2 . Par exemple: func(kwarg3=10) .
  • Dans Python 3, vous pouvez utiliser * seul pour indiquer que tous les arguments suivants doivent être spécifiés en tant que mots-clés. Par exemple, la fonction math.isclose dans Python 3.5 et math.isclose ultérieures est définie à l'aide de def math.isclose (a, b, *, rel_tol=1e-09, abs_tol=0.0) , ce qui signifie que les deux premiers arguments peuvent être fournis Les troisième et quatrième paramètres ne peuvent être fournis que sous forme d'arguments par mots clés.

Python 2.x ne prend pas en charge les paramètres par mot clé uniquement. Ce comportement peut être émulé avec kwargs :

def func(arg1, arg2=10, **kwargs):
    try:
        kwarg1 = kwargs.pop("kwarg1")
    except KeyError:
        raise TypeError("missing required keyword-only argument: 'kwarg1'")

    kwarg2 = kwargs.pop("kwarg2", 2)
    # function body ...

Remarque sur le nommage

La convention de nommage en option des arguments de position args et arguments optionnels mot - clé kwargs est juste une convention que vous pouvez utiliser tous les noms que vous voulez , mais il est utile de suivre la convention pour que les autres savent ce que vous faites, ou vous - même si s'il vous plaît faites plus tard.

Note sur l'unicité

Toute fonction peut être définie avec aucun ou un *args et aucun ou un **kwargs mais pas avec plus d'un de chacun. De plus, *args doit être le dernier argument positionnel et **kwargs doit être le dernier paramètre. Toute tentative d'utiliser plus d'un ou l' autre se traduira par une exception d'erreur de syntaxe.

Remarque sur les fonctions d'imbrication avec des arguments facultatifs

Il est possible d'imbriquer ces fonctions et la convention habituelle consiste à supprimer les éléments que le code a déjà traités, mais si vous transmettez les paramètres, vous devez passer des arguments positionnels optionnels avec un préfixe * et des mots-clés facultatifs args avec un préfixe ** , sinon args with soit passé comme une liste ou tuple et kwargs comme un seul dictionnaire. par exemple:

def fn(**kwargs):
    print(kwargs)
    f1(**kwargs)

def f1(**kwargs):
    print(len(kwargs))

fn(a=1, b=2)
# Out:
# {'a': 1, 'b': 2}
# 2