Python -Introduction aux closures
27 juil. 2016
Une closure est une fonction imbriquée dans une autre fonction avec des variables accessibles dans le scope de la closure uniquement.
La PEP de la closure : https://www.python.org/dev/peps/pep-0227/
adder est une fonction définie en interne et donc non accessible depuis l'extérieur.
Quand on utilise une closure,
Une closure va garder sa valeur lors de sa création, ici "base".
On peut accéder aux informations des variables de la closure avec la propriété cell_contents de __closure__.
On peut ajouter nonlocal pour la version 3 de python. Cela permet d'avoir l'état de cette fonction et de voir son évolution.
Comme nonlocal n'existe pas en python 2.7 il faut créer une variables dans un dictionnaire, accessible dans le scope de la closure.
Les performances sont au RDV car les variables locales (dans le scope de notre closure) sont acccessible rapidement.
Par contre attention car si l'algorithme de la closure devient trop complexe la maintenance ne sera pas facilité.
blog comments powered by Disqus
La PEP de la closure : https://www.python.org/dev/peps/pep-0227/
def make_adder(base):
... def adder(x):
... return base + x
... return adder
>>> add5 = make_adder(5)
>>> add5(6)
11
>>> add5(1)
6
adder est une fonction définie en interne et donc non accessible depuis l'extérieur.
Quand on utilise une closure,
>>> add5 = make_adder(5)
ce n'est pas le résultat qui est retourné mais la fonction elle même. C'est pour cela qu'il faut l'exécuter ensuite>>> add5(6)
Une closure va garder sa valeur lors de sa création, ici "base".
On peut accéder aux informations des variables de la closure avec la propriété cell_contents de __closure__.
>>> add5 .__closure__[0].cell_contents # donne la variable "base"
>>> add5 .__closure__[1].cell_contents # donne le 2ème paramètre de la fonction (n'existe pas dans mon example)
On peut ajouter nonlocal pour la version 3 de python. Cela permet d'avoir l'état de cette fonction et de voir son évolution.
def incr():
... percent = 0
...
... def add(valeur):
... nonlocal percent
... percent += valeur
... return percent
...
... return add
>>> add_value = incr()
>>> add_value(5)
5
>>> add_value(20)
25
Comme nonlocal n'existe pas en python 2.7 il faut créer une variables dans un dictionnaire, accessible dans le scope de la closure.
def outer():
... d = {'y' : 0}
... def inner():
... d['y'] += 1
... return d['y']
... return inner
>>> f = outer()
>>> print f()
1
>>> print f()
2
>>> print f()
3
Les performances sont au RDV car les variables locales (dans le scope de notre closure) sont acccessible rapidement.
Par contre attention car si l'algorithme de la closure devient trop complexe la maintenance ne sera pas facilité.