La limitation la plus importante, actuellement, c'est que vous ne pouvez pas attribuer à l'extérieur de la portée de la variable. En d'autres termes, les fermetures sont en lecture seule:
>>> def outer(x):
... def inner_reads():
... # Will return outer's 'x'.
... return x
... def inner_writes(y):
... # Will assign to a local 'x', not the outer 'x'
... x = y
... def inner_error(y):
... # Will produce an error: 'x' is local because of the assignment,
... # but we use it before it is assigned to.
... tmp = x
... x = y
... return tmp
... return inner_reads, inner_writes, inner_error
...
>>> inner_reads, inner_writes, inner_error = outer(5)
>>> inner_reads()
5
>>> inner_writes(10)
>>> inner_reads()
5
>>> inner_error(10)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 11, in inner_error
UnboundLocalError: local variable 'x' referenced before assignment
Un nom qui sera affectée à une portée locale (une fonction) est toujours local, sauf déclaration contraire. Alors qu'il est le "global" déclaration pour déclarer une variable globale de même lorsqu'il est affecté, il n'y a pas une telle déclaration pour entre les variables -- encore. En Python 3.0, il est (sera) le 'non' de la déclaration qui fait exactement ça.
Vous pouvez contourner cette limitation dans le temps, à l'aide d'un mutable type de conteneur:
>>> def outer(x):
... x = [x]
... def inner_reads():
... # Will return outer's x's first (and only) element.
... return x[0]
... def inner_writes(y):
... # Will look up outer's x, then mutate it.
... x[0] = y
... def inner_error(y):
... # Will now work, because 'x' is not assigned to, just referenced.
... tmp = x[0]
... x[0] = y
... return tmp
... return inner_reads, inner_writes, inner_error
...
>>> inner_reads, inner_writes, inner_error = outer(5)
>>> inner_reads()
5
>>> inner_writes(10)
>>> inner_reads()
10
>>> inner_error(15)
10
>>> inner_reads()
15