L'analyse des arguments et kwargs dans les décorateurs
J'ai une fonction qui prend en arguments et kwargs, et j'ai besoin de faire quelque chose dans ma décorateur basé sur la valeur de la 2e arg dans la fonction, comme dans le code ci-dessous:
def workaround_func():
def decorator(fn):
def case_decorator(*args, **kwargs):
if args[1] == 2:
print('The second argument is a 2!')
return fn(*args, **kwargs)
return case_decorator
return decorator
@workaround_func()
def my_func(arg1, arg2, kwarg1=None):
print('arg1: {} arg2: {}, kwargs: {}'.format(arg1, arg2, kwarg1))
Le problème est que python permet aux utilisateurs d'appeler la fonction avec le deuxième argument comme un régulier d'un argument OU d'un mot-clé-argument, donc si l'utilisateur appelle my_func
avec arg2
comme un kwarg, il soulève une IndexError
, voir ci-dessous:
In [8]: d.my_func(1, 2, kwarg1=3)
The second argument is a 2!
arg1: 1 arg2: 2, kwargs: 3
In [9]: d.my_func(1, arg2=2, kwarg1=3)
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
<ipython-input-9-87dc89222a9e> in <module>()
----> 1 d.my_func(1, arg2=2, kwarg1=3)
/home/camsparr/decoratorargs.py in case_decorator(*args, **kwargs)
2 def decorator(fn):
3 def case_decorator(*args, **kwargs):
----> 4 if args[1] == 2:
5 print('The second argument is a 2!')
6 return fn(*args, **kwargs)
IndexError: tuple index out of range
Est-il un moyen de contourner cela sans faire juste un try/except
et attraper le IndexError
?
OriginalL'auteur Cameron Sparr | 2013-09-19
Vous devez vous connecter pour publier un commentaire.
C'est le plus robuste de la façon que je peux penser à le manipuler... Le truc, c'est d'inspecter le nom de la deuxième argument. Ensuite, dans le décorateur, vous vérifiez pour voir si le nom est présent dans
kwargs
. Si oui, alors vous pouvez l'utiliser. Si non, alors vous utilisezargs
.l'exécution de cette résultats dans:
comme prévu.
OriginalL'auteur mgilson
J'ai trouvé une réponse à l'aide du python
decorator
paquet. Une caractéristique de ce paquet est qu'il préserve de position/mot-clé args peu importe la façon dont l'utilisateur passe. Il a l'avantage supplémentaire de réduire la quantité de code, donc mon code d'origine:devient:
OriginalL'auteur Cameron Sparr
Il semble que arg1 est un argument obligatoire, mais arg2 peut être facultatif. Vous pouvez modifier la ligne 3:
et ligne 6:
Si arg1 est aussi disponible en option, modifiez la ligne 3 avec arg1= "None" ou " =0 ou ="
Vous pouvez passer de position args par mot-clé si vous le souhaitez. Cela ne signifie pas que l'argument est facultatif (ce qui signifie vraiment qu'il a une valeur par défaut).
tcaswell a droite, il n'est pas que arg2 est facultatif, c'est que les gens peuvent passer de position args comme mot-clé args en python.
OriginalL'auteur chapelo