Maison  >  Article  >  développement back-end  >  Comprendre les décorateurs Python : une analyse approfondie

Comprendre les décorateurs Python : une analyse approfondie

Barbara Streisand
Barbara Streisandoriginal
2024-10-30 08:22:28343parcourir

Les décorateurs Python sont des outils puissants qui nous permettent de modifier ou d'améliorer le comportement des fonctions ou des méthodes. Les cas d'utilisation courants incluent la journalisation, l'autorisation, etc.
Cependant, lorsqu'on leur demande de définir un décorateur, beaucoup pourraient répondre :

C'est un wrapper pour une fonction.

Bien que cela soit techniquement correct, il se passe bien plus de choses sous le capot.

Disséquer un décorateur simple
Explorons un exemple simple :

def my_decorator(func):
    def wrapper(*args, **kwargs):
        print("Before calling the function")
        result = func(*args, **kwargs)
        print("After calling the function")
        return result
    return wrapper

@my_decorator
def say_hello(name):
    print(f"Hello, {name}!")

Ici, my_decorator est un décorateur pour la fonction say_hello. Lorsque say_hello est défini, il est automatiquement passé à my_decorator, transformant l'appel de fonction en :
say_hello = mon_décorateur(say_hello)

Quand cette transformation se produit-elle ?
Cette transformation se produit lors de la compilation du code, notamment au moment de la définition de la fonction, et non au moment de l'exécution.

Démonter le code
Pour comprendre comment fonctionnent les décorateurs à un niveau inférieur, nous pouvons utiliser le module dis pour examiner le bytecode de la fonction décorée :

import dis

@my_decorator
def say_hello(name):
    print(f"Hello, {name}!")

dis.dis(say_hello)

Répartition du bytecode

Le résultat de dis.dis(say_hello) pourrait ressembler à ceci :

Understanding Python Decorators: A Deep Dive
Explication du Bytecode

  1. Avant d'appeler la fonction

    • LOAD_GLOBAL : Charge la fonction d'impression.
    • LOAD_CONST : Charge le message 'Avant d'appeler la fonction'.
    • CALL_FUNCTION : impression des appels.
    • POP_TOP : rejette la valeur de retour.
  2. Appel de la fonction d'origine

    • LOAD_DEREF : Charge la fonction d'origine (func) capturée par la fermeture.
    • LOAD_FAST : charge les arguments de position et de mot-clé.
    • BUILD_MAP : crée un nouveau dictionnaire pour les arguments de mots-clés.
    • CALL_FUNCTION_EX : Appelle la fonction d'origine avec les arguments.
    • STORE_FAST : stocke le résultat dans une variable locale.
  3. Après avoir appelé la fonction

    • Semblable à la première partie, il appelle print pour afficher 'Après avoir appelé la fonction'.
    • Renvoyer le résultat
    • Charge la variable de résultat et la renvoie.

Conclusion
Les décorateurs Python sont plus que de simples wrappers de fonctions ; ils nous permettent de modifier le comportement de la fonction au moment de la définition. En comprenant leur fonctionnement et en examinant le bytecode, nous pouvons utiliser les décorateurs plus efficacement dans nos projets.

C'est tout pour l'instant ! S’il y a autre chose que vous aimeriez que j’aborde, faites-le-moi savoir !

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