Préserver les signatures des fonctions décorées
Les décorateurs sont un outil puissant pour améliorer la fonctionnalité des fonctions Python. Cependant, ils peuvent parfois masquer la signature de la fonction d'origine. Cela peut être problématique pour la documentation, le débogage et les outils automatisés.
Problème :
Considérons un décorateur générique qui convertit tous les arguments en entiers :
<code class="python">def args_as_ints(f): def g(*args, **kwargs): args = [int(x) for x in args] kwargs = dict((k, int(v)) for k, v in kwargs.items()) return f(*args, **kwargs) return g</code>
Pendant que la décoration fonctionne comme prévu, la signature de la fonction décorée est remplacée par "args, *kwargs", perdant ainsi des informations sur les arguments d'origine.
Solutions de contournement :
Plusieurs solutions de contournement existent, mais aucune n'est pleinement satisfaisante :
Solution :
<code class="python">import decorator @decorator.decorator def args_as_ints(f, *args, **kwargs): args = [int(x) for x in args] kwargs = dict((k, int(v)) for k, v in kwargs.items()) return f(*args, **kwargs)</code>
Ce décorateur préserve la signature de la fonction d'origine en la passant comme arguments à la fonction enveloppée.
Décorateur amélioré :<code class="python">@args_as_ints def funny_function(x, y, z=3): """Computes x*y + 2*z""" return x*y + 2*z</code>
>>> help(funny_function) Help on function funny_function in module __main__: funny_function(x, y, z=3) Computes x*y + 2*z
Python 3.4 :
<code class="python">import functools def args_as_ints(func): @functools.wraps(func) def wrapper(*args, **kwargs): args = [int(x) for x in args] kwargs = dict((k, int(v)) for k, v in kwargs.items()) return func(*args, **kwargs) return wrapper</code>
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!