Maison  >  Article  >  développement back-end  >  Qu’est-ce que la fermeture en Python ? Quelles sont les applications ?

Qu’est-ce que la fermeture en Python ? Quelles sont les applications ?

不言
不言avant
2018-10-13 14:53:212441parcourir

Le contenu de cet article porte sur ce qu'est la fermeture en Python ? Quelles sont les applications ? Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer. J'espère qu'il vous sera utile.

1. Fonction comme valeur de retour

Avant d'introduire la "fermeture", comprenons d'abord la situation de la fonction comme valeur de retour.
En plus de recevoir des fonctions en tant que paramètres, les fonctions d'ordre supérieur peuvent également renvoyer des fonctions en tant que valeurs de résultat. Par exemple, dans le décorateur présenté précédemment, les fonctions sont utilisées comme valeurs de retour.

2. Fermeture

1. Conditions et effets de la fermeture

Qu'est-ce que la fermeture ?
Lors de l'imbrication d'une autre fonction dans une fonction, une fermeture peut se produire si la fonction interne fait référence à une variable de la fonction externe.
Donc il y a trois conditions pour la génération de fermeture (une est indispensable) :

  • 1. Une fonction interne doit être imbriquée <.>

  • 2. La fonction interne doit faire référence à la variable de la fonction externe

  • 3. la fonction doit renvoyer la fonction interne

Alors pourquoi devrions-nous essayer les fermetures et quelles sont leurs fonctions ?

  • 1. Les fermetures peuvent obtenir différents résultats en fonction des variables locales des fonctions externes

  • 2. L'environnement d'exécution actuel peut être maintenu et le résultat de l'exécution dépend du dernier résultat d'exécution de la fonction

2. Exemple de fermeture

Chestnut 1 : Trouvez la somme de la séquence

>>> def calc_sum(*args):
...     ax = 0
...     for n in args:
...         ax = ax + n
...     return ax  # 返回变量
...
>>> calc_sum(1,2,3)
6
Cependant, si vous n'avez pas besoin d'obtenir le résultat de la sommation immédiatement, mais de le calculer selon les besoins dans le code suivant, que devez-vous faire ?

Nous ne pouvons pas renvoyer le résultat de la sommation, mais renvoyer la fonction de sommation, comme suit :

>>>def lazy_sum(*args):
...    def sum():            # sum()是内部函数,可以利用外部函数的参数
...        ax = 0
...        for n in args:    # sum()中使用外部函数的局部变量
...            ax = ax + n 
...        return ax
...    return sum            # 形成闭包,此时,*args保存在返回的函数中
...
>>>f = lazy_sum(1,3,5,7,9)
>>>f          # 此时返回的是求和函数
>>> f()       # 调用函数f()时,才真正计算求和的结果
25
Remarque :

La séquence d'exécution interne de la fonction lazy_sum(), lors de l'exécution f , s'exécute pour renvoyer sum, *args est enregistré dans la fonction return et ce qui est renvoyé est la fonction sum(). Lors de l’exécution de f(), cela équivaut à exécuter sum() et inclut *args.

Lorsque nous appelons lazy_sun(), une nouvelle fonction sera renvoyée à chaque fois, même si les mêmes paramètres sont passés, le résultat de l'appel f() ne sera pas affecté.

Vérifions le deuxième point :

# 但是调用 f1() 与f2()的调用结果互不影响
>>> f1 = lazy_sum(1,3,5,7,9)
>>> f2 = lazy_sum(1,3,5,7,9)
>>> f1
<function lazy_sum.<locals>.sum at 0x013DD618>
>>> f2
<function lazy_sum.<locals>.sum at 0x02F92DF8>
>>> f1 == f2
False
>>> f1() == f2()
True
>>> f1()
25
>>> f2()
25
>>> id(f1())
1627215984
>>> id(f2())
1627215984
Explication : Les positions des fonctions de retour de f1 et f2 sont différentes, donc le résultat de retour de f1==f2 est Faux.

Mais cela n'affecte pas le résultat final de l'exécution. Les résultats d'exécution de f1() et f2() sont tous deux 25, et ils peuvent être visualisés en utilisant id(), qui pointe vers la même zone.

Chestnut 2 :

def count():
    fs = []
    for i in range(1, 4):
        def f():         # 返回函数f()放在循环里
            return i*i
    fs.append(f)
    return fs
f1, f2, f3 = count()
Le résultat réel de l'exécution est : f1=9 f2=9 f3=9

Il peut être un peu différent de ce que vous pensiez réellement ([1 ,4,9]) pas pareil. Étant donné que la fonction f() est placée dans la boucle for, ce n'est qu'à la fin de la boucle que le résultat d'exécution 9 de i=3 est finalement renvoyé.
Il est donc préférable que la fonction de retour ne fasse référence à aucune variable de boucle ou quantité susceptible de changer par la suite. Alors comment le modifier ?

def count():
    def f(j):
        def g():
            return j*j      # 形成闭包
        return g
    fs = []
    for i in range(1, 4):
        fs.append(f(i))      # 一个i值进入后,f(i)立刻被执行,并加入到fs中
    return fs

f1, f2, f3 = count()  # 返回函数g没有引用j
Résultat final : [1,4,9] Autrement dit, f1=1 f2=4 f3=

Fonction anonyme lambda

Définition : Une fonction anonyme fait référence à un type de fonction ou de sous-programme qui n'a pas besoin de définir un nom de fonction identifiant. Python vous permet de créer des fonctions anonymes à l'aide du mot-clé lambda.

Syntaxe : paramètre lambda : expression

ou paramètre formel lambda 1,..., paramètre formel n : fonction (paramètre formel), paramètre d'entrée 1,..., paramètre d'entrée n

Remarque : 1. La fonction lambda peut recevoir n'importe quel nombre de paramètres et renvoyer la valeur d'une seule expression

2. La fonction lambda ne peut pas contenir de commandes et ne peut pas renvoyer plus d'une expression ;

Avantages : 1. Cela permet d'économiser le processus de définition des fonctions et de simplifier le code

2. Certaines fonctions abstraites qui ne seront pas réutilisées peuvent être définies avec lambda ;

Exemple :

>>> list( map( lambda x: x*x ,[1,2,3] ) )
[1, 4, 9]

implémente la fonction de : lamdba x : x*x. def f(x): return x*x

  • Vous pouvez attribuer une fonction anonyme à une variable, puis utiliser la variable pour appeler la fonction. Par exemple :

>>> f = lambda x:x*x  
>>> f(5) # 调用
>>> g = lambda x,y=2 : x*y
>>> g(2,4)
8
>>> g(2)    # 默认y=2
4
  • Vous pouvez renvoyer des fonctions anonymes comme valeurs de retour, par exemple :

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:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer