J'essaie de comprendre les éléments suivants concernant les fonctions et leurs arguments:arguments de la fonction Comprendre en Python
def print_my_arg(func, *args, **kwargs):
func(*args, **kwargs)
if 'my_arg' in kwargs:
print(' my_arg = {}'.format(kwargs['my_arg']))
def foo(call_no, my_arg='Default Value'):
print('call_no = {}'.format(call_no))
print_my_arg(foo, 0, my_arg='My Value 1')
print_my_arg(foo, 1, 'My Value 2')
print_my_arg(foo, 2)
Sortie:
call_no = 0
my_arg = My Value 1
call_no = 1 # I'd like to see 'My Value 2' here
call_no = 2 # I'd like to see 'Default Value' here
Il est évident que les gens sont libres d'invoquer des fonctions dans l'une des les moyens montrés ci-dessus, ce qui me fait me demander: pourquoi my_arg
ne va pas à kwargs
de toute façon? N'y a-t-il pas une manière uniforme d'accéder aux paramètres par nom (et non par position), qui ne dépend pas de la façon dont la fonction a été invoquée?
S'il vous plaît noter que:
Je ne suis pas intéressé par
print_my_args(func, call_no, my_arg)
, parce que je parle le cas où je ne connais pas la signature defunc
à l'avance et pourtant je veux savoir si un paramètre particulier existe (par nom). Il est clair que c'est lié aux décorateurs, mais j'ai écrit l'exemple d'une manière plus simple (ou je l'espère).
EDIT
Un grand merci pour les réponses sur inspect.signature. En utilisant, ma nouvelle version de print_my_arg()
est:
from inspect import signature
def print_my_arg (func, *args, **kwargs):
func (*args, **kwargs)
sig = signature (func)
if 'my_arg' not in sig.parameters: return
binding = sig.bind (*args, **kwargs)
binding.apply_defaults()
print (" my_arg = {}".format (binding.arguments [ 'my_arg' ]))
arguments positionnels ne * "vont "*' ** kwargs', parce que * ce ne sont pas des mots-clés *. Si vous voulez passer le second argument positionnel à la fonction, vous devrez le faire explicitement, il n'est pas du tout clair pourquoi vous attendiez un comportement différent. Vous pouvez forcer des arguments de mots clés si vous le souhaitez vraiment, voir par exemple. http://stackoverflow.com/a/37829651/3001761 – jonrsharpe
voulez-vous inspecter la ['signature'] (https://docs.python.org/3/library/inspect.html?highlight=signature#inspect. Signature.bind) de la fonction pour vérifier le nom de l'argument dans 'print_my_args'? alors vous pourriez faire 'passed_args = inspect.signature (func) .bind (* args, ** kwargs)' alors vérifiez si 'my_arg' est dans' passed_args'. –
http://stackoverflow.com/questions/3394835/args-and-kwargs –