web-dev-qa-db-fra.com

Comment trouver le nombre d'arguments d'une fonction Python?

Comment trouver le nombre d'arguments d'une fonction Python? J'ai besoin de savoir combien d'arguments normaux il a et combien d'arguments nommés.

Exemple:

def someMethod(self, arg1, kwarg1=None):
    pass

Cette méthode a 2 arguments et 1 argument nommé.

134
Georg Schölly

La réponse précédemment acceptée a été obsolète à partir de Python 3.0. À la place d'utiliser inspect.getargspec vous devriez maintenant opter pour la classe Signature qui l’a remplacée.

Créer une signature pour la fonction est facile via la fonction signature :

from inspect import signature

def someMethod(self, arg1, kwarg1=None):
    pass

sig = signature(someMethod)

Maintenant, vous pouvez soit visualiser rapidement ses paramètres en l’ajoutant str:

str(sig)  # returns: '(self, arg1, kwarg1=None)'

ou vous pouvez également obtenir un mappage de noms d'attributs sur des objets paramètres via sig.parameters.

params = sig.parameters 
print(params['kwarg1']) # prints: kwarg1=20

De plus, vous pouvez appeler len sur sig.parameters pour voir également le nombre d'arguments requis par cette fonction:

print(len(params))  # 3

Chaque entrée du mappage params est en fait un objet Parameter qui possède d’autres attributs qui vous facilitent la vie. Par exemple, saisir un paramètre et afficher sa valeur par défaut s’effectue désormais facilement avec:

kwarg1 = params['kwarg1']
kwarg1.default # returns: None

de même pour le reste des objets contenus dans parameters.


Comme pour Python 2.x utilisateurs, tandis que inspect.getargspec _ n'est pas obsolète, le langage le sera bientôt :-). La classe Signature n'est pas disponible dans le 2.x série et ne sera pas. Donc, vous devez toujours travailler avec inspect.getargspec .

En ce qui concerne la transition entre Python 2 et 3, si vous avez un code qui repose sur l'interface de getargspec dans Python 2 et passez à signature dans 3 est trop difficile, vous avez la précieuse option d’utiliser inspect.getfullargspec . Il offre une interface similaire à getargspec (un seul argument pouvant être appelé) afin de saisir les arguments d'une fonction tout en gérant des cas supplémentaires que getargspec ne fait pas:

from inspect import getfullargspec

def someMethod(self, arg1, kwarg1=None):
    pass

args = getfullargspec(someMethod)

Comme avec getargspec, getfullargspec renvoie un NamedTuple contenant les arguments.

print(args)
FullArgSpec(args=['self', 'arg1', 'kwarg1'], varargs=None, varkw=None, defaults=(None,), kwonlyargs=[], kwonlydefaults=None, annotations={})
88
import inspect
inspect.getargspec(someMethod)

voir le module inspecter

116
Jochen Ritzel
someMethod.func_code.co_argcount

ou, si le nom de la fonction actuelle est indéterminé:

import sys

sys._getframe().func_code.co_argcount
28
miaoever

inspect.getargspec ()

Obtenez les noms et les valeurs par défaut des arguments d’une fonction. Un tuple de quatre choses est renvoyé: (args, varargs, varkw, default). args est une liste de noms d'arguments (il peut contenir des listes imbriquées). varargs et varkw sont les noms des arguments * et ** ou None. defaults est un tuple de valeurs d'argument par défaut ou None s'il n'y a pas d'argument par défaut; si ce tuple a n éléments, ils correspondent aux n derniers éléments listés dans args.

Modifié dans la version 2.6: Renvoie une Tuple nommée ArgSpec (args, varargs, keywords, default).

Voir peut-vous-lister les arguments de mot-clé-un-fonction-python-reçoit .

16
gimel

Ajoutant à ce qui précède, j'ai aussi vu que la plupart du temps, la fonction help () aide vraiment

Par exemple, il donne tous les détails sur les arguments qu'il prend.

help(<method>)

donne le dessous

method(self, **kwargs) method of apiclient.discovery.Resource instance
Retrieves a report which is a collection of properties / statistics for a specific customer.

Args:
  date: string, Represents the date in yyyy-mm-dd format for which the data is to be fetched. (required)
  pageToken: string, Token to specify next page.
  parameters: string, Represents the application name, parameter name pairs to fetch in csv as app_name1:param_name1, app_name2:param_name2.

Returns:
  An object of the form:

    { # JSON template for a collection of usage reports.
    "nextPageToken": "A String", # Token for retrieving the next page
    "kind": "admin#reports#usageReports", # Th
5
Venu Murthy

Bonne nouvelle pour ceux qui veulent le faire de manière portable entre Python 2 et Python 3.6+: utilisez la méthode inspect.getfullargspec(). Cela fonctionne. dans les deux Python 2.x et 3.6+

Comme Jim Fasarakis Hilliard et d'autres l'ont fait remarquer, c'était comme ça:
1. Dans Python 2.x: utilisez inspect.getargspec()
2. Dans Python 3.x: utilisez la signature, car getargspec() et getfullargspec() étaient obsolètes.

Cependant, à partir de Python 3.6 (à la demande générale?), Les choses ont changé pour aller mieux:

De la Python 3 page de documentation :

inspect.getfullargspec (func)

Modifié dans la version 3.6: Cette méthode a déjà été documentée comme obsolète en faveur de signature() dans Python 3.5, mais cette décision a été inversée afin de restaurer une interface standard clairement prise en charge pour une source unique Python 2/3 code migrant en dehors de l’API getargspec() existante.

4
HAltos

inspect.getargspec () pour répondre à vos besoins

from inspect import getargspec

def func(a, b):
    pass
print len(getargspec(func).args)
2
Eds_k

Comme le suggèrent d'autres réponses, getargspec fonctionne bien tant que l'objet interrogé est en réalité une fonction. Cela ne fonctionne pas pour les fonctions intégrées telles que open, len, etc., et lève une exception. dans ces cas:

TypeError: <built-in function open> is not a Python function

La fonction ci-dessous (inspirée par cette réponse ) illustre une solution de contournement. Il retourne le nombre d'arguments attendus par f:

from inspect import isfunction, getargspec
def num_args(f):
  if isfunction(f):
    return len(getargspec(f).args)
  else:
    spec = f.__doc__.split('\n')[0]
    args = spec[spec.find('(')+1:spec.find(')')]
    return args.count(',')+1 if args else 0

L'idée est d'analyser la spécification de fonction du __doc__ chaîne. Évidemment, cela dépend du format de ladite chaîne, donc il n’est guère robuste!

1
starfry