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

DDD
Libérer: 2024-10-17 16:59:58
original
446 Les gens l'ont consulté

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>
Copier après la connexion

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>
Copier après la connexion
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>
Copier après la connexion

>>> help(funny_function)
Help on function funny_function in module __main__:

funny_function(x, y, z=3)
    Computes x*y + 2*z
Copier après la connexion
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>
Copier après la connexion
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!

source:php
Déclaration de ce site Web
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
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal