Python Language
* args et ** kwargs
Recherche…
Remarques
Il y a quelques choses à noter:
Les noms
args
etkwargs
sont utilisés par convention, ils ne font pas partie de la spécification du langage. Ainsi, ceux-ci sont équivalents:def func(*args, **kwargs): print(args) print(kwargs)
def func(*a, **b): print(a) print(b)
Vous ne pouvez pas avoir plus d'un
args
ou plus d'un paramètrekwargs
(toutefois, ils ne sont pas obligatoires)def func(*args1, *args2): # File "<stdin>", line 1 # def test(*args1, *args2): # ^ # SyntaxError: invalid syntax
def test(**kwargs1, **kwargs2): # File "<stdin>", line 1 # def test(**kwargs1, **kwargs2): # ^ # SyntaxError: invalid syntax
Si un argument de position suit
*args
, ce sont des arguments de mots-clés uniquement pouvant être transmis uniquement par nom. Une seule étoile peut être utilisée à la place de*args
pour forcer les valeurs à être des arguments de mot-clé sans fournir de liste de paramètres variadiques. Les listes de paramètres par mot clé uniquement sont uniquement disponibles dans Python 3.def func(a, b, *args, x, y): print(a, b, args, x, y) func(1, 2, 3, 4, x=5, y=6) #>>> 1, 2, (3, 4), 5, 6
def func(a, b, *, x, y): print(a, b, x, y) func(1, 2, x=5, y=6) #>>> 1, 2, 5, 6
**kwargs
doit venir en dernier dans la liste des paramètres.def test(**kwargs, *args): # File "<stdin>", line 1 # def test(**kwargs, *args): # ^ # SyntaxError: invalid syntax
Utiliser * args lors de l'écriture de fonctions
Vous pouvez utiliser l'étoile * lors de l'écriture d'une fonction pour collecter tous les arguments de position (c'est-à-dire sans nom) dans un tuple:
def print_args(farg, *args):
print("formal arg: %s" % farg)
for arg in args:
print("another positional arg: %s" % arg)
Méthode d'appel:
print_args(1, "two", 3)
Dans cet appel, farg sera affecté comme toujours, et les deux autres seront introduits dans le tuple args, dans l'ordre dans lequel ils ont été reçus.
Utiliser ** kwargs pour écrire des fonctions
Vous pouvez définir une fonction qui prend un nombre arbitraire d'arguments par mot-clé en utilisant l'étoile double **
avant un nom de paramètre:
def print_kwargs(**kwargs):
print(kwargs)
Lors de l'appel de la méthode, Python va construire un dictionnaire de tous les arguments de mots clés et le rendre disponible dans le corps de la fonction:
print_kwargs(a="two", b=3)
# prints: "{a: "two", b=3}"
Notez que le paramètre ** kwargs dans la définition de la fonction doit toujours être le dernier paramètre, et qu'il ne correspondra qu'aux arguments transmis après les précédents.
def example(a, **kw):
print kw
example(a=2, b=3, c=4) # => {'b': 3, 'c': 4}
À l'intérieur du corps de la fonction, kwargs
est manipulé de la même manière qu'un dictionnaire; pour accéder à des éléments individuels dans kwargs
vous suffit de les parcourir comme vous le feriez avec un dictionnaire normal:
def print_kwargs(**kwargs):
for key in kwargs:
print("key = {0}, value = {1}".format(key, kwargs[key]))
Maintenant, appeler print_kwargs(a="two", b=1)
affiche la sortie suivante:
print_kwargs(a = "two", b = 1)
key = a, value = "two"
key = b, value = 1
Utiliser * args lors de l'appel de fonctions
Un cas d'utilisation courant pour *args
dans une définition de fonction consiste à déléguer le traitement à une fonction encapsulée ou héritée. Un exemple typique pourrait être la méthode __init__
une classe
class A(object):
def __init__(self, b, c):
self.y = b
self.z = c
class B(A):
def __init__(self, a, *args, **kwargs):
super(B, self).__init__(*args, **kwargs)
self.x = a
Ici, le a
paramètre est traité par la classe enfant après que tous les autres arguments (position et mot - clé) sont passés sur - et traitées par - la classe de base.
Par exemple:
b = B(1, 2, 3)
b.x # 1
b.y # 2
b.z # 3
Ce qui se passe ici, c'est que la fonction __init__
la classe B
voit les arguments 1, 2, 3
. Il sait qu'il doit prendre un argument positionnel ( a
), donc il saisit le premier argument passé dans ( 1
), donc dans le cadre de la fonction a == 1
.
Ensuite, il voit qu'il doit prendre un nombre arbitraire d'arguments positionnels ( *args
), il prend donc le reste des arguments positionnels passés dans ( 1, 2
) et les place dans *args
. Maintenant (dans le cadre de la fonction) args == [2, 3]
.
Ensuite, il appelle la fonction __init__
classe A
avec *args
. Python voit le *
devant args et "décompresse" la liste en arguments. Dans cet exemple, lorsque la classe B
's __init__
fonction appelle la classe A
' s __init__
fonction, il sera transmis les arguments 2, 3
(c. -à- A(2, 3)
).
Enfin, il définit sa propre propriété x
sur le premier argument positionnel a
, qui est égal à 1
.
Utiliser ** kwargs lors de l'appel de fonctions
Vous pouvez utiliser un dictionnaire pour attribuer des valeurs aux paramètres de la fonction. en utilisant des paramètres name comme clés dans le dictionnaire et la valeur de ces arguments liés à chaque clé:
def test_func(arg1, arg2, arg3): # Usual function with three arguments
print("arg1: %s" % arg1)
print("arg2: %s" % arg2)
print("arg3: %s" % arg3)
# Note that dictionaries are unordered, so we can switch arg2 and arg3. Only the names matter.
kwargs = {"arg3": 3, "arg2": "two"}
# Bind the first argument (ie. arg1) to 1, and use the kwargs dictionary to bind the others
test_var_args_call(1, **kwargs)
Utiliser * args lors de l'appel de fonctions
L'utilisation de l'opérateur *
sur un argument lors de l'appel d'une fonction consiste à décompresser la liste ou un argument tuple
def print_args(arg1, arg2):
print(str(arg1) + str(arg2))
a = [1,2]
b = tuple([3,4])
print_args(*a)
# 12
print_args(*b)
# 34
Notez que la longueur de l'argument étoilé doit être égale au nombre d'arguments de la fonction.
Un idiome commun de python est d'utiliser l'opérateur de décompression *
avec la fonction zip
pour inverser ses effets:
a = [1,3,5,7,9]
b = [2,4,6,8,10]
zipped = zip(a,b)
# [(1,2), (3,4), (5,6), (7,8), (9,10)]
zip(*zipped)
# (1,3,5,7,9), (2,4,6,8,10)
Arguments relatifs aux mots clés uniquement et aux mots clés
Python 3 vous permet de définir des arguments de fonction qui ne peuvent être assignés que par mot-clé, même sans valeurs par défaut. Cela se fait en utilisant star * pour consommer des paramètres de position supplémentaires sans définir les paramètres du mot-clé. Tous les arguments après le * sont des arguments uniquement par mot clé (c'est-à-dire non positionnels). Notez que si les arguments contenant uniquement des mots clés ne sont pas définis par défaut, ils sont toujours requis lors de l'appel de la fonction.
def print_args(arg1, *args, keyword_required, keyword_only=True):
print("first positional arg: {}".format(arg1))
for arg in args:
print("another positional arg: {}".format(arg))
print("keyword_required value: {}".format(keyword_required))
print("keyword_only value: {}".format(keyword_only))
print(1, 2, 3, 4) # TypeError: print_args() missing 1 required keyword-only argument: 'keyword_required'
print(1, 2, 3, keyword_required=4)
# first positional arg: 1
# another positional arg: 2
# another positional arg: 3
# keyword_required value: 4
# keyword_only value: True
Remplir les valeurs de kwarg avec un dictionnaire
def foobar(foo=None, bar=None):
return "{}{}".format(foo, bar)
values = {"foo": "foo", "bar": "bar"}
foobar(**values) # "foobar"
** kwargs et valeurs par défaut
Utiliser les valeurs par défaut avec ** kwargs
def fun(**kwargs):
print kwargs.get('value', 0)
fun()
# print 0
fun(value=1)
# print 1