web-dev-qa-db-fra.com

Python, arguments de mots clés par défaut après des arguments positionnels de longueur variable

Je pensais pouvoir utiliser des paramètres nommés après des paramètres positionnels de longueur variable dans un appel de fonction en Python 2, mais j'obtiens un SyntaxError lors de l'importation d'un python classe. J'écris avec la méthode "get" suivante, par exemple:

class Foo(object):
    def __init__(self):
        print "You have created a Foo."

    def get(self, *args, raw=False, vars=None):
        print len(args)
        print raw
        print vars

L'erreur ressemble à:

def get(self, *args, raw=False, vars=None):
                     ^
SyntaxError: invalid syntax

Je voudrais pouvoir appeler la méthode de plusieurs manières:

f = Foo()
f.get(arg1, arg2)
f.get(arg1, raw=True)
f.get(arg1, arg2, raw=True, vars=something)

etc.

77
jkmacc

Cela fonctionne, mais uniquement dans Python 3. Voir PEP 102 . En jetant un coup d'œil sur les documents "Quoi de neuf", il semble qu'il n'y ait pas de backport 2.x , donc vous n'avez pas de chance. Vous devrez accepter tous les arguments de mot-clé (**kwargs) et les analyser manuellement. Vous pouvez utiliser d.get(k, default) pour obtenir d[k] ou default si ce n'est pas le cas. Pour supprimer un argument de kwargs, par exemple avant d'appeler une méthode de super classe ', utilisez d.pop.


Notez que dans def get(self, *args, raw=False, vars=None):, raw=False Et vars=None N'ont rien à voir avec les arguments des mots clés. Ce sont des valeurs d'argument par défaut. Les arguments avec une valeur par défaut peuvent être passés en position et les arguments sans valeur par défaut peuvent être passés par mot-clé:

def f(a=1): pass
f(2)  # works, passing a positionally
def f(a): pass
f(a=2)  # works, passing a by keyword

De même, les arguments de mots clés uniquement n'ont pas besoin d'avoir une valeur par défaut. Venir après l'argument *args Est ce qui les marque comme mot-clé uniquement, pas la présence d'une valeur par défaut:

def f(*args, a): pass
# a is a mandatory, keyword-only argument
68
user395760

La syntaxe de Python n'autorise pas les arguments de variable dans les arguments de fonction et de mot-clé avec la valeur par défaut en même temps. Si vous devez avoir des arguments de mots clés avec un nombre arbitraire d'arguments positionnels, vous devez également autoriser un nombre arbitraire d'arguments de mots clés.

Il s'agit d'un modèle courant pour fournir des valeurs par défaut pour les arguments de mots clés, ainsi que pour autoriser un nombre illimité d'arguments positionnels:

def foo(*args, **kwargs):
   raw = kwargs.pop('raw', False)
   vars = kwargs.pop('vars', None)

Si vous n'utilisez pas du tout les arguments de mots clés supplémentaires, vous n'avez rien à craindre. Cela rend la fonction un peu moins auto-documentée, que vous pouvez rattraper avec une docstring correctement écrite.

47
Imran