94 votes

Récupérer tous les arguments et valeurs passés à une fonction

J'ai une fonction Python, fetch_data qui se connecte à une API distante, récupère des données et les renvoie dans un objet de réponse. Cela ressemble un peu à ce qui suit :

def fetch_data(self, foo, bar, baz, **kwargs):
    response = Response()
    # Do various things, get some data
    return response

Maintenant, il est possible que les données de réponse disent "J'ai plus de données, appelez-moi avec une incrémentation page paramètre pour en obtenir plus". Ainsi, j'aimerais essentiellement stocker "l'appel de la méthode" (fonction, paramètres) dans l'objet de réponse, de sorte que je puisse ensuite avoir une Response.get_more() qui examine la fonction stockée et les paramètres, et appelle à nouveau la fonction avec (presque) les mêmes paramètres, en renvoyant un nouveau fichier Response

Maintenant si fetch_data ont été définis comme suit fetch_data(*args, **kwargs) Je pourrais juste stocker (fetch_data, args, kwargs) en response . Cependant, j'ai self , foo , bar et baz de s'inquiéter - je pourrais simplement stocker (fetch_data, foo, bar, baz, kwargs) mais c'est une quantité de répétition hautement indésirable.

Essentiellement, j'essaie de trouver comment, à partir d'une fonction, obtenir une image complètement remplie. *args et **kwargs y compris les paramètres nommés de la fonction.

9voto

Alex Points 346

Je crois que la méthode de choix est getcallargs de inspect car il renvoie des arguments réels avec lesquels la fonction sera invoquée. Vous passez une fonction et des args et kwargs à celle-ci ( inspect.getcallargs(func, *args, **kwds) ), il retournera les arguments réels de la méthode utilisés pour l'invocation, en tenant compte des valeurs par défaut et d'autres éléments. Regardez l'exemple ci-dessous.

from inspect import getcallargs

# we have a function with such signature
def show_params(first, second, third=3):
    pass

# if you wanted to invoke it with such params (you could get them from a decorator as example)
args = [1, 2, 5]
kwargs = {}
print(getcallargs(show_params, *args, **kwargs))
#{'first': 1, 'second': 2, 'third': 5}

# here we didn't specify value for d
args = [1, 2, 3, 4]
kwargs = {}

# ----------------------------------------------------------
# but d has default value =7
def show_params1(first, *second, d = 7):
    pass

print(getcallargs(show_params1, *args, **kwargs))
# it will consider b to be equal to default value 7 as it is in real method invocation
# {'first': 1, 'second': (2, 3, 4), 'd': 7}

# ----------------------------------------------------------
args = [1]
kwargs = {"d": 4}

def show_params2(first, d=3):
    pass

print(getcallargs(show_params2, *args, **kwargs))
#{'first': 1, 'd': 4}

https://docs.python.org/3/library/inspect.html

6voto

Vitaly Zdanevich Points 2264
import inspect

def f(x, y):
    print(
        inspect.getargvalues(inspect.currentframe())
    )

f(1, 2)

Résultat :
ArgInfo(args=['x', 'y'], varargs=None, keywords=None, locals={'y': 2, 'x': 1})

1voto

Scott Hunter Points 10356

Kwargs n'aura pas 'foo', 'bar' ou 'bad' comme clés, donc vous pouvez ajouter ces entrées (avec leurs valeurs) à kwargs et simplement stocker (fetch_data, kwargs).

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