Les Crash-Devs d'un Passionné

Introduction aux closures

/Catégorie/python

Temps de lecture : 2 minutes

Une closure est une fonction imbriquée dans une autre fonction avec des variables accessibles dans le scope de la closure uniquement.

La PEP 227 de la closure :

clipboard
Copier le code
1
2
3
4
5
6
7
8
9
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.

clipboard
Copier le code
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
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.

clipboard
Copier le code
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
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é.