Maison  >  Article  >  développement back-end  >  Exemples d'utilisation des fermetures en Python

Exemples d'utilisation des fermetures en Python

黄舟
黄舟original
2017-10-02 19:43:43989parcourir

Cet article présente principalement les informations pertinentes sur l'utilisation des fermetures dans le didacticiel de base de Python. J'espère que cet article pourra vous aider. Les amis dans le besoin peuvent se référer au

Tutoriel de base de Python. utiliser des fermetures

Préface :

La fermeture (closure) est une structure grammaticale importante dans la programmation fonctionnelle. La programmation fonctionnelle est un paradigme de programmation (et la programmation procédurale et la programmation orientée objet sont également des paradigmes de programmation). En programmation orientée processus, nous avons vu des fonctions ; en programmation orientée objet, nous avons vu des objets. L'objectif fondamental des fonctions et des objets est d'organiser le code d'une certaine manière logique et d'améliorer la réutilisabilité du code. La fermeture est également une structure d'organisation du code, qui améliore également la réutilisabilité du code.

Différentes langues implémentent les fermetures de différentes manières. Python est basé sur des objets de fonction et prend en charge la structure syntaxique des fermetures (nous avons vu à plusieurs reprises que Python utilise des objets pour implémenter une syntaxe spéciale dans des méthodes spéciales et des multi-paradigmes). Tout en Python est un objet, et la structure grammaticale de la fonction est également un objet. Dans un objet fonction, nous utilisons l'objet fonction comme un objet normal, par exemple en changeant le nom de l'objet fonction ou en passant l'objet fonction en tant que paramètre.

Portée de l'objet fonction

Comme les autres objets, l'objet fonction a également sa portée de survie, qui est la portée de l'objet fonction. Les objets fonction sont définis à l'aide d'instructions def et la portée de l'objet fonction est la même que le niveau auquel se trouve def. Par exemple, dans le code suivant, la ligne de fonction que nous définissons dans la portée d'affiliation de la fonction line_conf ne peut être appelée que dans la portée d'affiliation de line_conf.


def line_conf():
  def line(x):
    return 2*x+1
  print(line(5))  # within the scope


line_conf()
print(line(5))    # out of the scope

La fonction ligne définit une ligne droite (y = 2x + 1). Comme vous pouvez le voir, la fonction line peut être appelée dans line_conf(), mais appeler line en dehors de la portée provoquera l'erreur suivante :


NameError: name 'line' is not defined

signifie qu'à ce stade temps Déjà en dehors du champ d'application.

De même, si vous utilisez lambda pour définir une fonction, la portée de l'objet fonction est la même que le niveau où se trouve le lambda.

Fermeture

Une fonction est un objet, elle peut donc être utilisée comme résultat de retour d'une fonction.


def line_conf():
  def line(x):
    return 2*x+1
  return line    # return a function object

my_line = line_conf()
print(my_line(5))

Le code ci-dessus peut être exécuté avec succès. Le résultat de retour de line_conf est affecté à l'objet ligne. Le code ci-dessus imprimera 11.

Que se passe-t-il si une variable externe est référencée dans la définition de line() ?


def line_conf():
  b = 15
  def line(x):
    return 2*x+b
  return line    # return a function object

b = 5
my_line = line_conf()
print(my_line(5))

On peut voir que la variable de haut niveau b est référencée dans le bloc de programme subordonné défini par ligne, mais l'information b existe en dehors de la définition de ligne ( b La définition de n'est pas dans le bloc de ligne subordonné). On appelle b la variable d'environnement de la ligne. En fait, lorsque line est utilisée comme valeur de retour de line_conf, line inclut déjà la valeur de b (bien que b ne soit pas affilié à line).

Le code ci-dessus imprimera 25, c'est-à-dire que la valeur b référencée par la ligne est la valeur b disponible pour référence lorsque l'objet fonction est défini, pas la valeur b lorsqu'il est utilisé.

Une fonction et ses variables d'environnement forment ensemble une

fermeture. En Python, ce qu'on appelle la fermeture est un objet fonction qui contient la valeur d'une variable d'environnement. Les valeurs des variables d'environnement sont stockées dans l'attribut __closure__ de l'objet fonction. Par exemple, le code suivant :


def line_conf():
  b = 15
  def line(x):
    return 2*x+b
  return line    # return a function object

b = 5
my_line = line_conf()
print(my_line.__closure__)
print(my_line.__closure__[0].cell_contents)
__closure__ contient un tuple. Chaque élément de ce tuple est un objet de type cellule. On voit que la première cellule contient l'entier 15, qui est la valeur de la variable d'environnement b lors de la création de la fermeture.

Regardons un exemple pratique de fermeture :


def line_conf(a, b):
  def line(x):
    return ax + b
  return line

line1 = line_conf(1, 1)
line2 = line_conf(4, 5)
print(line1(5), line2(5))
Dans cet exemple, la ligne de fonction et les variables d'environnement a et b forment une fermeture . Lors de la création de la fermeture, nous précisons les valeurs de ces deux variables d'environnement via les paramètres a et b de line_conf. De cette manière, nous déterminons la forme finale de la fonction (y = x + 1 et y = 4x + 5). . Il suffit de transformer les paramètres a et b pour obtenir différentes fonctions d'expression en ligne droite. De là, nous pouvons voir que les fermetures ont également pour effet d’améliorer la réutilisabilité du code.

S'il n'y a pas de fermeture, nous devons spécifier a, b, x chaque fois que nous créons une fonction de ligne droite. De cette façon, nous devons transmettre plus de paramètres et réduire la portabilité du code. Avec les fermetures, nous créons en fait des fonctionnels. La fonction ligne définit une fonction au sens large. Certains aspects de cette fonction sont déjà déterminés (il doit s'agir d'une ligne droite), mais d'autres aspects (comme les paramètres a et b sont indéterminés). Par la suite, nous déterminons la fonction finale sous la forme d'une fermeture en fonction des paramètres passés par line_conf.

Fermetures et opérations parallèles

Les fermetures réduisent efficacement le nombre de paramètres qui doivent être définis pour une fonction. Cela a des implications importantes pour les opérations parallèles. Dans un environnement informatique parallèle, nous pouvons confier à chaque ordinateur la responsabilité d’une fonction, puis concaténer la sortie d’un ordinateur avec l’entrée de l’ordinateur suivant. En fin de compte, nous travaillons comme une chaîne de montage, avec des données entrées à une extrémité d’une série de clusters d’ordinateurs et des données sorties à l’autre extrémité. Cette situation est mieux adaptée aux fonctions avec une seule entrée de paramètre. Les fermetures peuvent atteindre cet objectif.

L'informatique parallèle est en train de devenir un point chaud. C’est également une raison importante pour laquelle la programmation fonctionnelle redevient populaire. La programmation fonctionnelle existait dès les années 1950, mais elle n’était pas largement utilisée. Cependant, le processus de clustering parallèle en pipeline que nous avons décrit ci-dessus est parfaitement adapté à la programmation fonctionnelle. En raison des avantages naturels de la programmation fonctionnelle, de plus en plus de langages ont commencé à ajouter la prise en charge du paradigme de programmation fonctionnelle.

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