web-dev-qa-db-fra.com

Obtenir une liste / Tuple / dict des arguments passés à une fonction?

Étant donné la fonction suivante:

def foo(a, b, c):
    pass

Comment obtenir une liste/Tuple/dict/etc des arguments passés, sans avoir à construire moi-même la structure?

Plus précisément, je recherche la version Python du mot clé arguments de JavaScript ou la méthode func_get_args() de PHP.

Ce que je recherche pas est une solution utilisant *args Ou **kwargs; J'ai besoin de spécifier les noms des arguments dans la définition de la fonction (pour m'assurer qu'ils sont transmis) mais dans la fonction, je veux travailler avec eux dans une structure de type liste ou dict.

59
Phillip B Oldham

Vous pouvez utiliser locals() pour obtenir un dict des variables locales dans votre fonction, comme ceci:

def foo(a, b, c):
    print locals()

>>> foo(1, 2, 3)
{'a': 1, 'c': 3, 'b': 2}

C'est un peu hackeux, cependant, car locals() renvoie toutes les variables dans la portée locale, pas seulement les arguments passés à la fonction, donc si vous ne l'appelez pas tout en haut de la fonction, le résultat peut contenir plus d'informations que vous ne le souhaitez:

def foo(a, b, c):
    x = 4
    y = 5
    print locals()

>>> foo(1, 2, 3)
{'y': 5, 'x': 4, 'c': 3, 'b': 2, 'a': 1}

Je préfère construire un dict ou une liste des variables dont vous avez besoin en haut de votre fonction, comme suggéré dans les autres réponses. Il est plus explicite et communique l'intention de votre code d'une manière plus claire, à mon humble avis.

76
Pär Wieslander

Vous pouvez utiliser le module d'inspection:

def foo(x):
    return x

inspect.getargspec(foo)
Out[23]: ArgSpec(args=['x'], varargs=None, keywords=None, defaults=None)

Il s'agit d'un doublon de this et this .

7
kroger

J'utiliserais *args ou **kwargs et lève une exception si les arguments ne sont pas comme prévu

Si vous voulez avoir les mêmes erreurs que celles vérifiées par python vous pouvez faire quelque chose comme

def check_arguments(function_name,args,arg_names):
    missing_count = len(arg_names) - len(args)
    if missing_count > 0:
        if missing_count == 1:
            raise TypeError(function_name+"() missing 1 required positionnal argument: "+repr(arg_names[-1]))
        else:
            raise TypeError(function_name+"() missing "+str(missing_count)+" required positionnal argument: "+", ".join([repr(name) for name in arg_names][-missing_count:-1])+ " and "+repr(arg_names[-1]))

utiliser avec quelque chose comme

def f(*args):
    check_arguments("f",args,["a","b","c"])
    #whatever you want
    ...
4
Xavier Combelle

Vous avez spécifié les paramètres dans l'en-tête?

Pourquoi n'utilisez-vous pas simplement ces mêmes informations dans le corps?

def foo(a, b, c):
   params = [a, b, c]

Qu'est-ce que j'ai raté?

1
Oddthinking

Vous pouvez en créer une liste en utilisant:

 args = [a, b, c] 

Vous pouvez facilement en créer un tuple à l'aide de:

 args = (a, b, c) 
1

Une solution, en utilisant des décorateurs, est ici .

1
Marcelo Cantos

De la réponse acceptée d'une question en double (plus ancienne ??) https://stackoverflow.com/a/582206/1136458 :

    frame = inspect.currentframe()
    args, _, _, values = inspect.getargvalues(frame)
1
lib