Alors que la plupart des réponses disent que, par exemple,
def f(**kwargs):
foo = kwargs.pop('foo')
bar = kwargs.pop('bar')
...etc...
est le même que"
def f(foo=None, bar=None, **kwargs):
...etc...
ce n'est pas vrai. Dans ce dernier cas, f
peut être appelé as f(23, 42)
, tandis que le premier cas accepte uniquement les arguments nommés - pas d'appels de position. Souvent, vous voulez permettre à l'appelant une flexibilité maximale et, par conséquent, la deuxième forme, comme l'affirment la plupart des réponses, est préférable: mais ce n'est pas toujours le cas. Lorsque vous acceptez de nombreux paramètres facultatifs dont généralement seuls quelques-uns sont transmis, il peut être une excellente idée (éviter les accidents et le code illisible sur vos sites d'appels!) De forcer l'utilisation d'arguments nommés - en threading.Thread
est un exemple. La première forme est de savoir comment implémenter cela dans Python 2.
L'idiome est si important qu'en Python 3 il a maintenant une syntaxe de support spéciale: chaque argument après un simple *
dans la def
signature est uniquement mot-clé, c'est-à-dire, ne peut pas être passé comme argument positionnel, mais seulement comme argument nommé. Donc, en Python 3, vous pouvez coder ce qui précède comme suit:
def f(*, foo=None, bar=None, **kwargs):
...etc...
En effet, dans Python 3, vous pouvez même avoir des arguments de mots clés uniquement qui ne sont pas facultatifs (ceux sans valeur par défaut).
Cependant, Python 2 a encore de longues années de vie productive à venir, il est donc préférable de ne pas oublier les techniques et les idiomes qui vous permettent d'implémenter dans Python 2 des idées de conception importantes qui sont directement prises en charge dans le langage Python 3!