Maison >développement back-end >Tutoriel Python >Comment conserver les signatures de fonction lors de l'utilisation de décorateurs en Python ?

Comment conserver les signatures de fonction lors de l'utilisation de décorateurs en Python ?

DDD
DDDoriginal
2024-10-17 16:59:58471parcourir

How to Preserve Function Signatures When Using Decorators in Python?

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 :

  • Copier manuellement la signature dans la docstring.
  • Créer un nouveau décorateur pour chaque signature spécifique.
  • Créer un nouveau décorateur pour chaque signature spécifique.
Construire manuellement la fonction décorée avec exec.

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>
le module décorateur offre une solution élégante :

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
Maintenant, la fonction décorée funny_function conserve sa signature originale :

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>
Pour Python 3.4 et supérieur, functools.wraps fournit une solution similaire :

En utilisant ces techniques, les décorateurs peuvent améliorer la fonctionnalité des fonctions tout en préservant leurs signatures originales, garantissant ainsi la clarté et la cohérence de la base de 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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn