Découvrez les fonctions d'ordre supérieur et la notation de décorateur de Python, qui sont des versions un peu meilleures des fonctions.
Lorsqu'il y a un ensemble A et un ensemble B, la règle «f» qui détermine de manière unique l'élément «f (a)» de l'ensemble B pour tout élément «a» de l'ensemble A est appelée une fonction de A à B.
Considérons une fonction times2 qui double ses arguments et renvoie
def times2(i):
return i * 2
A ce moment, si 0, 1, 2 est donné comme ʻi`,
times2(0) == 0times2(1) == 2times2(2) == 4Et une fonction de set ([0,1,2]) à un ensemble d'entiers est définie.

Les fonctions ont les effets suivants en programmation:
En maîtrisant les fonctions d'ordre supérieur expliquées ci-dessous, il y a plus de situations où ces effets peuvent être obtenus.
Considérez le processus consistant à appliquer la même valeur 1 aux fonctions qui multiplient l'argument par 0, multiplient par 1 et doublent les arguments.
times0(1) == 0times1(1) == 1times2(1) == 2Par rapport à la définition de la fonction times2: set ([0, 1, 2]) -> Int plus tôt, la règle de correspondance de l'ensemble des fonctions set ([times0, times1, times2]) à l'ensemble des entiers Je peux le voir.
apply1(times0) == 0apply1(times1) == 1apply1(times2) == 2
ʻApply1` peut être implémenté comme suit
def apply1(f):
return f(1)
Une fonction qui prend une fonction comme argument (ou une fonction qui renvoie une fonction comme vu dans la section suivante) est appelée une fonction d'ordre supérieur.
Fonction d'ordre supérieur qui prend un nombre comme argument et renvoie une fonction
def times_n(n):
def f(i):
return n * i
return f
Si vous utilisez, vous pouvez utiliser les paramètres times0, times1, times2 qui sont sortis plus tôt.
times0 = times_n(0)
times1 = times_n(1)
times2 = times_n(2)
Peut être défini comme.

>>> apply1(times0)
0
>>> apply1(times1)
1
>>> apply1(times2)
2
Si vous utilisez une fonction d'ordre supérieur qui prend une fonction comme argument et renvoie la fonction
Etc. peut être écrit sous une forme réutilisable.
def dot(g):
"f -> g . f"
def func(f):
def composite(i):
return g(f(i))
return composite
return func
>>> (lambda i: i*2)((lambda i: i+5)(1))
12
>>> f = dot(lambda i: i*2)(lambda i: i+5)
>>> f(1)
12
Quand il y a une fonction d'ordre supérieur décorateur qui prend une fonction comme argument et renvoie la fonction
@decorator
def function(argument):
# ...
Remplacera «fonction» par «décorateur (fonction)».
fonction = décorateur (fonction) après avoir défini fonctionEcrivez un décorateur qui imprime un journal des appels de fonction et l'appliquez à des fonctions récursives inefficaces.
def trace(function):
"Décorateur pour imprimer le journal des appels"
def inner(*args):
"Imprimer les journaux d'appels avant et après la fonction"
print("{0}{1}".format(function.__name__, args))
ret = function(*args)
print("{0}{1} ==> {2}".format(function.__name__, args, ret))
return ret
return inner
@trace
def fib(n):
"Trouvez le numéro de Fibonacci"
if n == 0:
return 0
if n == 1:
return 1
return fib(n-2) + fib(n-1)
Vous pouvez voir que le même calcul a été fait plusieurs fois.
% python3 -c 'import fib; fib.fib(4)'
fib(4,)
fib(2,)
fib(0,)
fib(0,) ==> 0
fib(1,)
fib(1,) ==> 1
fib(2,) ==> 1
fib(3,)
fib(1,)
fib(1,) ==> 1
fib(2,)
fib(0,)
fib(0,) ==> 0
fib(1,)
fib(1,) ==> 1
fib(2,) ==> 1
fib(3,) ==> 2
fib(4,) ==> 3
Dans l'exemple précédent, le docstirng de fib et le nom de la fonction seraient ʻinner`.
>>> fib.__doc__
'Imprimer les journaux d'appels avant et après la fonction'
>>> fib.__name__
'inner'
→ Il est douloureux d'appliquer le même décorateur à plusieurs fonctions
from functools import wraps
def trace(function):
"Décorateur pour imprimer le journal des appels"
@wraps(function)
def inner(*args):
"Imprimer les journaux d'appels avant et après la fonction"
...
Si tu pars
>>> fib.__doc__
'Trouvez le numéro de Fibonacci'
>>> fib.__name__
'fib'
Et hérite de la docstring et du nom de la fonction d'origine. Utile lors de l'affichage des traces de pile
* args et ** kwargsVous pouvez écrire des décorateurs plus polyvalents en utilisant * args et ** kwargs.
Les décorateurs ne doivent pas nécessairement remplacer une fonction par une nouvelle. Par exemple
setattr et retourne la fonction d'origineEtc. sont également possibles.
Recommended Posts