Un article pour résoudre le problème de la programmation fonctionnelle avec des fermetures Python

programmation fonctionnelle

concept de programmation fonctionnelle, nous pouvons plus ou moins avons entendu, juste entendu quand le sommeil inconnu Li, pense que c'est un concept très sombre de la science et de la technologie. Mais, en fait, sa signification est très simple, mais beaucoup étendant l'utilisation riche.

Dans le langage de programmation au début, pas beaucoup de temps, nous allons la langue en  langage de haut niveau avec le langage de bas niveau  . Tels que le langage assembleur, est langage de bas niveau, presque tout paquet ni avons-nous besoin d' un opérateur d'affectation au registre d'appel manuellement. Et de ces instructions en langage de haut niveau axé sur la machine qui se dégage en faveur de orientée processus ou objet. En d' autres termes , nous écrivons le code pour certains d'entre eux est un calcul informatique ou abstraire des objets. Si vous avez étudié orienté objet, et vous constaterez que par rapport à axé sur les processus, plus un peu orienté objet niveau d'abstraction, fait un ensemble plus complet.

Après l'orienté objet, nous pouvons faire abstraction et l'encapsulation de celui-ci? Ce tour de la programmation fonctionnelle.

Fonction nous le savons tous, est un programme que nous définissons, ses entrées et sorties sont déterminées. Nous écrivons des fonctions qui peuvent être appelées partout. Étant donné que la fonction si facile à utiliser, vous pouvez  mettre en fonction renvoie également un paramètre variable et passer  il?

OK, c'est le plus de fonctionnalités de programmation intuitives et fonctionnelles. En d' autres termes , nous écrivons une fonction peut également être utilisé comme une variable, les deux peuvent être utilisés pour attribuer, le transfert peut également être utilisé, et peuvent être retournés. Par conséquent, grandement facilité notre code, mais ce n'est pas pour le bien, au contraire , il apporte beaucoup de problèmes, le problème le plus intuitif est en raison des paramètres fonction peuvent également être transmis à une autre fonction, ce qui peut  conduire à la fonction les calculs deviennent si incertains  , beaucoup au - delà de nos attentes de ce qui peut arriver.

Ainsi, la programmation fonctionnelle sont les avantages et les inconvénients, et il simplifie vraiment beaucoup de problèmes, mais a créé de nombreux nouveaux problèmes, nous devons être prudents dans le processus utilisé.

Fonction de retour entrant

Avant de présenter le filtre, la carte, et réduire le tri sur mesure, alors qu'en fait, nous avons utilisé le concept de la programmation fonctionnelle.

Par exemple, quand si on passe un tableau d'objets, nous espérons que nous avons mis au point sur la base du type de terrain, en quelque sorte, nous appelons triés cette fois -ci nous avons souvent besoin de passer une  fonction anonyme  , utilisé pour développer le genre de terrain. En fait, la fonction anonyme entrant, en fait, est le plus reflète la programmation fonctionnelle intuitive:

sorted(kids, key=lambda x: x['score'])

De plus, nous pouvons également renvoyer une fonction, par exemple, nous examinons un exemple:

def delay_sum(nums):
    def sum():
        s = 0
        for i in nums:
            s += i
        return s
    return sum

Si cette fois, nous appelons delay_sum passer une série de chiffres, qu'avons-nous?

La réponse est une fonction, on peut diriger la sortie, vu de l'information contenue dans cette impression:

>>> delay_sum([1, 3, 4, 2])
<function delay_sum.<locals>.sum at 0x1018659e0>

Nous voulons obtenir le résultat de l'opération devrait être la façon de le faire? Est également très simple, nous utilisons une variable pour le recevoir, vous pouvez exécuter cette nouvelle variable:

>>> f = delay_sum([1, 3, 4, 2])
>>> f()
10

Ceci a l'avantage que nous pouvons  calculer retarder  si la programmation fonctionnelle n'est pas utilisé, alors nous avons besoin lorsque vous appelez delay_sum cette fonction pour calculer les résultats. Si cette opération est très faible Heureusement, si cette opération est assez grand, il fera les frais généraux. , Probablement tard dans la nuit et sera utilisé lorsque l' on calcule les résultats, les résultats ne peuvent pas être utilisées immédiatement. Cela étant le cas, nous revenons à une fonction au lieu de l'opération, lorsque le besoin réel d'utiliser ultérieurement les résultats, retardant ainsi les opérations. Ceci est aussi beaucoup d'idées communes cadre informatique, comme  la Spark  .

fermetures

Le regard Let l'exemple que nous venons de citer, en fonction juste de delay_sum au sein de notre interne à atteindre une fonction somme, nous appelons les paramètres de la fonction delay_sum passé dans cette fonction qui. Ce genre de  portée externe  variables sont référencées par une fonction appelée interne  des fermetures  .

En fait, ce concept est l'image, parce que ces données d'appel de fonction interne de l'appelant est fermé, complètement une boîte noire, à moins que nous considérons le code source, sinon nous ne savons pas la source de celui - ci entre les données. En plus de ne pas connaître la source, il est plus important est qu'il est une variable de référence en dehors de la fonction, car elle est la variable la note est dynamique. Que nous  pouvons changer l'effet de la fermeture de l'opération en changeant la valeur de certaines variables externes  .

Ceci est un peu difficile à prononcer, nous regardons un exemple simple. En Python a une fonction appelée Math.pow qui est en fait la puissance de calcul. Par exemple, nous voulons calculer le carré de x, alors nous devrions écrire:

math.pow(x, 2)

Mais si le scénario actuel nous avons seulement besoin de calculer la place, chaque fois que nous avons un laissez-passer et passer le supplément 2 sera très gênant, cette fois-ci, nous utilisons une fermeture, les opérations peut être simplifiée:

def mypow(num):
    def pw(x):
        return math.pow(x, num)
    return pw
    
pow2 = mypow(2)
print(pow2(10))

En fermeture, nous avons  mis une seconde variable fixe  , nous ne aurons besoin d'utiliser l'original peut être réalisé pow2 Math.pow (x, 2) la fonction. Si nous devons changer la demande soudainement puissance de calcul de la puissance 3 ou 4, il suffit de modifier les paramètres entrants MYPOW peuvent, sans modification du code.

En fait , c'est la plus grande fermeture de scénarios d'utilisation, nous pouvons  par la fermeture atteint des caractéristiques très flexibles  , ainsi que la modification de certaines des fonctions gérées par la configuration sans qu'il soit nécessaire d'écrire le code par les morts. Pour en savoir pour l'industrie, la ligne de code ne peut être modifié, en particulier le client, comme Apple Store ou Android parmi un magasin de package, seul l'utilisateur mise à jour manuelle va tirer. Si un problème se produit, et presque aucun moyen de modifier l'utilisateur les mises à jour ne peut attendre manuellement. Par conséquent, le fonctionnement normal est d'utiliser une fonction de fermeture flexible similaire,  changer la logique du code en modifiant le mode de configuration  .

En outre , il y a une fermeture qui peut utiliser  l'environnement variable temporaire ou l' exécution  .

Par exemple, nous examinons le code suivant:

def step(x=0):
    x += 5
    return x

Ce n'est pas une fonction de l'utilisation de fermetures, peu importe combien de fois nous appelons, la réponse est 5, x + = exécution du résultat après 5 et ne sera pas enregistrée lorsque la fonction retourne, cette valeur sera mise en scène abandonnée . Que faire si je  veux appeler à chaque fois que les résultats sont basés sur le dernier appel  , ce qui signifie que chaque fois que nous modifions l'action peut être sauvé, plutôt que défausse il?

Cette fois-ci vous devez utiliser la fermeture:

def test(x=0):
    def step():
        nonlocal x
        x += 5
        return x
    return step
    
t = test()
t()
>>> 5
t()
>>> 10

Telle est notre valeur x est emmagasinée,  sera cumulatif chaque modification  , plutôt que mis au rebut. Il convient de noter que nous utilisons un nouveau mot - clé est appelé  nonlocal  , qui est unique parmi les mots - clés utilisés python3 pour déclarer la variable actuelle x n'est pas une variable locale, donc interpréteur Python va les trouver cette variable globale x, de sorte que le procédé de test associé qui peut être passé dans le paramètre x. les responsables python2 ne sont pas mis à jour, pas recommandé.

Puisque tout Python est un objet qui est, si nous  fonctionnons comme la fermeture de la couche extérieure est une classe  si, dans les fermetures de fait et la différence de classe n'est pas grande, on peut même retourner le colis à la fonction de fermeture de la fonction de corrélation, donc presque un objet de. Regardez un exemple:

def student():
    name = 'xiaoming'
    
    def stu():
        return name
        
    def set_name(value):
        nonlocal name
        name = value
        
    stu.set_name = set_name
    return stu
    
stu = student()
stu.set_name('xiaohong')
print(stu())

La dernière opération est Xiaohong, parce que nous appelons le changement set_name la valeur de l'extérieur de fermeture. Soit, mais dans des circonstances normales , nous ne l' utiliserions pas. Et écrire une classe par rapport au moyen de la fermeture de  la vitesse de fonctionnement sera plus rapide . Raison de plus subtile, car aucun de fermeture de pointeur auto, sauvant ainsi beaucoup d'accès et les variables d' exploitation, de sorte que le calcul de certains plus rapidement. Mais les fermetures se livrent à des objets pseudo est  de ne pas l' héritage d'utilisation, dérivées des  méthodes, mais aussi hors de l' air et de l' utilisation normale, donc nous savons qu'il ya une telle méthode peut être une réalité et ne pas être utilisé.

fermetures pit

Bien que la fermeture facile à utiliser, mais ne faites pas attention, il est très facile à pas sur la fosse, voici quelques fosse commune.

Bouclages ne peuvent pas accéder directement à des variables externes

Ceci est quelque chose que nous avons déjà mentionné, la fermeture dont nous  ne pouvons pas accéder directement à des variables externes  doivent être marquées par mot - clé nonlocal, sinon il est se plaindra.

def test():
    n = 0
    def t():
        n += 5
        return n
    return t

Par exemple, c'est le cas, il erreur:

Fermeture variable de boucle qui ne peut pas être utilisé

Les bouclages ont un gros problème est  que vous ne pouvez pas utiliser une variable de boucle  , fosse profonde cachée, simplement parce que d'un point de vue logique est le code ne peut pas être trouvé. C'est logiquement pas de code de problème lorsqu'il est exécuté ont tendance à notre grande surprise, que nous devons avoir une profonde compréhension des principes sous - jacents peuvent être trouvés, par exemple, nous examinons un exemple:

def test(x):
    fs = []
    for i in range(3):
        def f():
            return x + i
        fs.append(f)
    return fs


fs = test(3)
for f in fs:
    print(f())

Dans l'exemple ci-dessus eux, nous utilisons une boucle pour créer trois fermetures, nous utilisons trois fs fermetures de magasins et retour. Nous appelons le test, pour obtenir les trois fermetures, et nous avons été appelés.

Cette logique ne semble pas être un problème, selon la raison, ces trois fermetures est créé par une boucle, et dans laquelle nous avons utilisé la variable de la boucle de fermeture i. Que , selon nos idées, le résultat de la production finale devrait être [3, 4, 5], mais malheureusement, nous obtenons la finale  résulte [5, 5, 5]  .

Il semble étrange, et qui n'a pas été surprenant, car  la variable de boucle i est pas dans la création de fermeture quand il a mis bon  . Mais quand nous exécutons la fermeture, nous allons chercher les valeurs de i, évidemment , lorsque nous courons la fermeture, le cycle correspondant a été exécuté plus, cette fois je me suis arrêté au 2. Par conséquent, les résultats de ces trois fermeture est 2 + 3 est 5. La fosse est un interpréteur Python pour la logique qui a conduit à la fermeture de l'exécution de Ecrivons logique est juste, mais il ne suit pas notre logique, il devrait donc être prudent, si vous oubliez, vous voulez passer pour en savoir sera difficile à déboguer.

résumé

Bien que sur la surface il y a des problèmes et la fermeture des puits, mais il est encore nos  fonctionnalités avancées Python couramment utilisées  , et il est également à la base de beaucoup d' autres utilisation élevée. Ainsi , nous apprenons à comprendre et à la fermeture est très nécessaire, ne pas indigne.

En fait, non seulement la fermeture, la plupart des caractéristiques sont plus ou moins très abstraites ont de tels problèmes. Parce que quand nous faisons abstraction, bien sûr nous simplifie le code, une plus grande flexibilité, mais en même temps nous faisons également  la courbe d'apprentissage devient plus raide  , ce qui porte plus que nous devons comprendre et retenir le contenu. Il est également un compromis, faciles à utiliser sur la nature du code nécessaire à payer, facile à utiliser et signifie souvent rigides plus rigide. Pour ce problème, nous devons maintenir l'état d'esprit, mais les bonnes nouvelles à première vue quand

Publié 151 articles originaux · a gagné les éloges 4 · vues 10000 +

Je suppose que tu aimes

Origine blog.csdn.net/weixin_46089319/article/details/105364151
conseillé
Classement