116 votes

Pouvez-vous lister les arguments de mots clés qu'une fonction Python reçoit?

J'ai un dict, j'ai besoin de passer clés/valeurs de mot-clé arguments.. Par exemple..

d_args = {'kw1': 'value1', 'kw2': 'value2'}
example(**d_args)

Cela fonctionne bien, mais si il y a des valeurs dans la d_args dict qui ne sont pas acceptées par l' example de la fonction, il est évident qu'elle meurt.. - Dire, si l'exemple de la fonction est définie comme def example(kw2):

C'est un problème puisque je n'ai pas de contrôle de la génération de l' d_args, ou l' example fonction.. Ils viennent tous deux de modules externes, et example accepte uniquement certains des mots clés les arguments de la dict..

Idéalement, je voudrais juste faire

parsed_kwargs = feedparser.parse(the_url)
valid_kwargs = get_valid_kwargs(parsed_kwargs, valid_for = PyRSS2Gen.RSS2)
PyRSS2Gen.RSS2(**valid_kwargs)

Je vais probablement juste de filtrer l'dict, à partir d'une liste de mot clé valide-arguments, mais je me demandais: Est-il possible d'en programmant liste des mots clés les arguments d'une fonction spécifique?

163voto

Brian Points 48423

Un peu plus agréable que d'inspecter le code objet directement et de travailler sur les variables est d'utiliser l'inspecter module.

>>> import inspect
>>> def func(a,b,c=42, *args, **kwargs): pass
>>> inspect.getargspec(func)
(['a', 'b', 'c'], 'args', 'kwargs', (42,))

Si vous voulez savoir si son remboursables avec un ensemble particulier de args, vous avez besoin de la args sans un défaut déjà spécifié. Il peut être obtenu par:

def getRequiredArgs(func):
    args, varargs, varkw, defaults = inspect.getargspec(func)
    if defaults:
        args = args[:-len(defaults)]
    return args   # *args and **kwargs are not required, so ignore them.

Ensuite, une fonction pour dire ce que vous êtes absent de votre dict est:

def missingArgs(func, argdict):
    return set(getRequiredArgs(func)).difference(argdict)

De même, pour vérifier invalide args, utilisez:

def invalidArgs(func, argdict):
    args, varargs, varkw, defaults = inspect.getargspec(func)
    if varkw: return set()  # All accepted
    return set(argdict) - set(args)

Et donc un test complet si il est appelable est :

def isCallableWithArgs(func, argdict):
    return not missingArgs(func, argdict) and not invalidArgs(func, argdict)

(C'est bon uniquement pour python arg de l'analyse. Tout d'exécution des contrôles pour des valeurs non valides dans kwargs ne peuvent évidemment pas être détecté.)

33voto

DzinX Points 13452

Cela permettra d'imprimer les noms de tous les praticables arguments, mot-clé et non-mot-clé:

def func(one, two="value"):
    y = one, two
    return y
print func.func_code.co_varnames[:func.func_code.co_argcount]

C'est parce que la première co_varnames sont toujours les paramètres (à côté sont des variables locales, comme y dans l'exemple ci-dessus).

Alors maintenant, vous pourriez avoir une fonction:

def getValidArgs(func, argsDict):
    '''Return dictionary without invalid function arguments.'''
    validArgs = func.func_code.co_varnames[:func.func_code.co_argcount]
    return dict((key, value) for key, value in argsDict.iteritems() 
                if key in validArgs)

Qui vous pouvez ensuite utiliser comme ceci:

>>> func(**getValidArgs(func, args))


EDIT: UN petit ajout: si vous avez vraiment besoin que le mot arguments d'une fonction, vous pouvez utiliser l' func_defaults attribut de les extraire:

def getValidKwargs(func, argsDict):
    validArgs = func.func_code.co_varnames[:func.func_code.co_argcount]
    kwargsLen = len(func.func_defaults) # number of keyword arguments
    validKwargs = validArgs[-kwargsLen:] # because kwargs are last
    return dict((key, value) for key, value in argsDict.iteritems() 
                if key in validKwargs)

Vous pouvez maintenant appeler votre fonction connue args, mais extrait kwargs, par exemple:

func(param1, param2, **getValidKwargs(func, kwargsDict))

Cela suppose qu' func n'utilise pas de *args ou **kwargs de la magie dans sa signature.

9voto

J.F. Sebastian Points 102961

En Python 3.0:

 >>> import inspect
>>> import fileinput
>>> print(inspect.getfullargspec(fileinput.input))
FullArgSpec(args=['files', 'inplace', 'backup', 'bufsize', 'mode', 'openhook'],
varargs=None, varkw=None, defaults=(None, 0, '', 0, 'r', None), kwonlyargs=[], 
kwdefaults=None, annotations={})
 

3voto

Claudiu Points 58398

Étendre la réponse de DzinX:

 argnames = example.func_code.co_varnames[:func.func_code.co_argcount]
args = dict((key, val) for key,val in d_args.iteritems() if key in argnames)
example(**args)
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X