Fabrication industrielle
Internet des objets industriel | Matériaux industriels | Entretien et réparation d'équipement | Programmation industrielle |
home  MfgRobots >> Fabrication industrielle >  >> Industrial programming >> Python

Fermetures Python

Fermetures Python

Dans ce didacticiel, vous découvrirez la fermeture Python, comment définir une fermeture et les raisons pour lesquelles vous devriez l'utiliser.

Variable non locale dans une fonction imbriquée

Avant d'entrer dans ce qu'est une fermeture, nous devons d'abord comprendre ce qu'est une fonction imbriquée et une variable non locale.

Une fonction définie à l'intérieur d'une autre fonction est appelée une fonction imbriquée. Les fonctions imbriquées peuvent accéder aux variables de la portée englobante.

En Python, ces variables non locales sont en lecture seule par défaut et nous devons les déclarer explicitement comme non locales (en utilisant le mot-clé nonlocal) afin de les modifier.

Voici un exemple de fonction imbriquée accédant à une variable non locale.

def print_msg(msg):
    # This is the outer enclosing function

    def printer():
        # This is the nested function
        print(msg)

    printer()

# We execute the function
# Output: Hello
print_msg("Hello")

Sortie

Hello

Nous pouvons voir que le printer() imbriqué la fonction a pu accéder au msg non local variable de la fonction englobante.

Définir une fonction de fermeture

Dans l'exemple ci-dessus, que se passerait-il si la dernière ligne de la fonction print_msg() a renvoyé le printer() fonction au lieu de l'appeler? Cela signifie que la fonction a été définie comme suit :

def print_msg(msg):
    # This is the outer enclosing function

    def printer():
        # This is the nested function
        print(msg)

    return printer  # returns the nested function


# Now let's try calling this function.
# Output: Hello
another = print_msg("Hello")
another()

Sortie

Hello

C'est inhabituel.

Le print_msg() la fonction a été appelée avec la chaîne "Hello" et la fonction renvoyée était liée au nom un autre . Sur appel another() , le message était toujours mémorisé bien que nous ayons déjà fini d'exécuter le print_msg() fonction.

Cette technique par laquelle certaines données ("Hello dans ce cas) est attaché au code est appelé fermeture en Python .

Cette valeur dans la portée englobante est mémorisée même lorsque la variable sort de la portée ou que la fonction elle-même est supprimée de l'espace de noms actuel.

Essayez d'exécuter ce qui suit dans le shell Python pour voir le résultat.

>>> del print_msg
>>> another()
Hello
>>> print_msg("Hello")
Traceback (most recent call last):
...
NameError: name 'print_msg' is not defined

Ici, la fonction renvoyée fonctionne toujours même lorsque la fonction d'origine a été supprimée.

Quand avons-nous des fermetures ?

Comme le montre l'exemple ci-dessus, nous avons une fermeture en Python lorsqu'une fonction imbriquée fait référence à une valeur dans sa portée englobante.

Les critères qui doivent être remplis pour créer une fermeture en Python sont résumés dans les points suivants.

  • Nous devons avoir une fonction imbriquée (fonction à l'intérieur d'une fonction).
  • La fonction imbriquée doit faire référence à une valeur définie dans la fonction englobante.
  • La fonction englobante doit renvoyer la fonction imbriquée.

Quand utiliser les fermetures ?

Alors, à quoi servent les bouclages ?

Les fermetures peuvent éviter l'utilisation de valeurs globales et fournissent une certaine forme de masquage des données. Il peut également fournir une solution orientée objet au problème.

Lorsqu'il y a peu de méthodes (une méthode dans la plupart des cas) à implémenter dans une classe, les fermetures peuvent fournir une solution alternative et plus élégante. Mais lorsque le nombre d'attributs et de méthodes augmente, il est préférable d'implémenter une classe.

Voici un exemple simple où une fermeture peut être préférable à la définition d'une classe et à la création d'objets. Mais la préférence vous appartient.

def make_multiplier_of(n):
    def multiplier(x):
        return x * n
    return multiplier


# Multiplier of 3
times3 = make_multiplier_of(3)

# Multiplier of 5
times5 = make_multiplier_of(5)

# Output: 27
print(times3(9))

# Output: 15
print(times5(3))

# Output: 30
print(times5(times3(2)))

Sortie

27
15
30

Les décorateurs Python font également un usage intensif des fermetures.

Pour conclure, il est bon de souligner que les valeurs qui sont incluses dans la fonction de fermeture peuvent être trouvées.

Tous les objets de fonction ont un __closure__ attribut qui renvoie un tuple d'objets cellule s'il s'agit d'une fonction de fermeture. En se référant à l'exemple ci-dessus, nous savons times3 et times5 sont des fonctions de fermeture.

>>> make_multiplier_of.__closure__
>>> times3.__closure__
(<cell at 0x0000000002D155B8: int object at 0x000000001E39B6E0>,)

L'objet cellule a l'attribut cell_contents qui stocke la valeur fermée.

>>> times3.__closure__[0].cell_contents
3
>>> times5.__closure__[0].cell_contents
5

Python

  1. Types de données Python
  2. Opérateurs Python
  3. Instruction de passe Python
  4. Fonction Python Anonyme/Lambda
  5. Dictionnaire Python
  6. Générateurs Python
  7. Décorateurs Python
  8. Python String strip() Fonction avec EXAMPLE
  9. Fonctions Python Lambda avec EXEMPLES