Étant donné la fonction Python:
def a_method(arg1, arg2):
pass
Comment puis-je extraire le nombre et les noms des arguments. C'est-à-dire, étant donné que j'ai une référence à func
, je veux que le func.[something]
retour ("arg1", "arg2")
.
Le scénario d'utilisation pour cela est que j'ai un décorateur, et je souhaite utiliser les arguments de méthode dans le même ordre qu'ils apparaissent pour la fonction réelle comme clé. C'est-à-dire, à quoi ressemblerait le décorateur imprimé "a,b"
lors de mon appel a_method("a", "b")
?
Réponses:
Jetez un oeil au
inspect
module - cela fera l'inspection des différentes propriétés des objets de code pour vous.Les autres résultats sont le nom des variables * args et ** kwargs et les valeurs par défaut fournies. c'est à dire.
Notez que certains callables peuvent ne pas être introspectables dans certaines implémentations de Python. Par exemple, dans CPython, certaines fonctions intégrées définies en C ne fournissent aucune métadonnée sur leurs arguments. En conséquence, vous obtiendrez un
ValueError
si vous utilisezinspect.getfullargspec()
une fonction intégrée.Depuis Python 3.3, vous pouvez utiliser
inspect.signature()
pour voir la signature d'appel d'un objet appelable:la source
(4,)
correspondc
spécifiquement au paramètre de mot-clé ?inspect.getargspec
est obsolète , mais le remplacement l'estinspect.getfullargspec
.En CPython, le nombre d'arguments est
et leurs noms sont au début de
Ce sont des détails d'implémentation de CPython, donc cela ne fonctionne probablement pas dans d'autres implémentations de Python, comme IronPython et Jython.
Une façon portable d'admettre des arguments "pass-through" consiste à définir votre fonction avec la signature
func(*args, **kwargs)
. Ceci est beaucoup utilisé par exemple dans matplotlib , où la couche API externe transmet de nombreux arguments de mots clés à l'API de niveau inférieur.la source
*args
, par exemple:def foo(x, *args, y, **kwargs): # foo.__code__.co_argcount == 1
Dans une méthode décoratrice, vous pouvez répertorier les arguments de la méthode d'origine de cette façon:
Si ce
**kwargs
sont importants pour vous, alors ce sera un peu compliqué:Exemple:
la source
Je pense que ce que vous cherchez, c'est la méthode des locaux -
la source
La version Python 3 est:
La méthode renvoie un dictionnaire contenant à la fois args et kwargs.
la source
[:fn.__code__.co_argcount]
est très important si vous recherchez les arguments de la fonction - sinon il inclut également les noms créés dans la fonction.Voici quelque chose qui, je pense, fonctionnera pour ce que vous voulez, en utilisant un décorateur.
Exécutez-le, il produira la sortie suivante:
la source
Python 3.5+:
Alors auparavant:
Maintenant:
Tester:
Étant donné que nous avons la fonction «fonction» qui prend l'argument «arg», cela sera évalué comme Vrai, sinon comme Faux.
Exemple de la console Python:
la source
En Python 3. + avec l'
Signature
objet à portée de main, un moyen facile d'obtenir un mappage entre les noms d'argument et les valeurs, utilise labind()
méthode de Signature !Par exemple, voici un décorateur pour imprimer une carte comme ça:
la source
Voici une autre façon d'obtenir les paramètres de la fonction sans utiliser de module.
Production:
la source
Renvoie une liste de noms d'arguments, prend en charge les fonctions partielles et régulières:
la source
Mise à jour pour la réponse de Brian :
Si une fonction en Python 3 a des arguments de mots clés uniquement, vous devez utiliser
inspect.getfullargspec
:donne ceci:
la source
En python 3, ci-dessous est de faire
*args
et**kwargs
en undict
(utiliserOrderedDict
pour python <3.6 pour maintenir lesdict
commandes):la source
inspect.signature
Est très lent. Le moyen le plus rapide estla source
Pour mettre à jour un peu la réponse de Brian , il y a maintenant une belle rétroportage
inspect.signature
que vous pouvez utiliser dans les versions de python âgées:funcsigs
. Donc, ma préférence personnelle irait pourPour le plaisir, si vous êtes intéressé à jouer avec des
Signature
objets et même à créer des fonctions avec des signatures aléatoires de manière dynamique, vous pouvez jeter un œil à monmakefun
projet.la source
Qu'en est- il
dir()
etvars()
maintenant?Semble faire exactement ce qui est demandé super simplement ...
Doit être appelé depuis la portée de la fonction.
Mais attention, il renverra toutes les variables locales, alors assurez-vous de le faire au tout début de la fonction si nécessaire.
Notez également que, comme indiqué dans les commentaires, cela ne permet pas de le faire depuis l'extérieur du champ d'application. Donc pas exactement le scénario d'OP mais correspond toujours au titre de la question. D'où ma réponse.
la source