6 ms·
> Python doesn't even have closures. So what's this? >>> x = 1 >>> def f(y): return y + x ... >>> f(2) 3 EDIT: Note that my example work
by tome 11y ago
> Python doesn't even have closures.
So what's this?
>>> x = 1
>>> def f(y): return y + x
...
>>> f(2)
3
EDIT: Note that my example works even if the definition of x and f appear within the definition of another function. If closed-over variables must be mutable then Haskell doesn't have closures!
- aidos 11y agoJust been reading up on this. Python has sort of read only closures where the free variables are stored against the functions. You can't alter a variable inside the closure like you can in JS. Personally, I don't mind - I'd rather have a better idea of which scopes are changing which information, but I don't think they're considered "true closures." More over here - http://stackoverflow.com/a/23558809/171450 http://stackoverflow.com/a/23558809/171450
- gte525u 11y agoThis is incorrect for at least python 3.x I.e., Python 3.4.3 (default, Apr 7 2015, 08:05:21) >>> def mk_generator(initial): ... var = initial ... def increment(count=1): ... nonlocal var ... var += count ... return var ... return increment ... >>> a = mk_generator(3) >>> b = mk_generator(10) >>> a(1) 4 >>> b <function mk_generator.<locals>.increment at 0x1040a7d08> >>> b() 11 >>> b() 12 >>> a(3) 7
- josteink 11y agoReference to a global, shared variable.
- espadrine 11y agoI believe you are confusing closures with scope. Closures define the set of variables whose lifetime extends the function they are in because of their use in another function. For instance: ;; Function that returns a function that counts even numbers (define (even) (let ((x 0)) (lambda () (set! x (+ x 2)) x))) (define count (even)) (count) ; → 2 (count) ; → 4 In Python: def even(): x = 0 def add(): x += 2 return x return add count = even() count() # → UnboundLocalError: local variable 'x' referenced before assignment That said, Python does support a less convenient style of closures — it works if the variable is a container (such as a list, a dictionary or an object).
- voyou 11y agoPython supports closures even when the variable isn't a container. For instance: def add_double(n): x = n * 2 def add(y): return x + y return add f = add_double(1) f(2) # -> 4 What python versions prior to 3 didn't support is rebinding a variable from an enclosing scope; not because of any fundamental feature of the implementation, but because there was no syntactic way to differentiate between a assigning to a variable in an enclosing scope, and creating a variable in the current scope. So x += 2 is short for x = x + 2, which python interprets as creating a new variable x in the current scope and then trying to access that variable before it's been assigned. Python 3 introduced a syntax to specify that you wanted to assign to a variable from an enclosing scope, the 'nonlocal' keyword. So your example would be: def even(): x = 0 def add(): nonlocal x x += 2 return x return add count = even() count() # → 2 count() # → 4
- PuercoPop 11y agoSo C has closures now? #include <stdio.h> int x = 1; int f(int y) { return x + y; } int main(argv, argc) { printf("f(2): %i\n", f(2)); } The reason they are called closures is because they close over the, lexical, environment where the function was defined. Python doesn't have lexical scope, hence it doesn't have closures.
- dalke 11y ago"Python doesn't have lexical scope" Can you explain why https://en.wikipedia.org/wiki/Python_syntax_and_semantics#Closures https://en.wikipedia.org/wiki/Python_syntax_and_semantics#Cl... says: > Python has had support for lexical closures since version 2.2. ... Python's syntax, though, sometimes leads programmers of other languages to think that closures are not supported. Variable scope in Python is implicitly determined by the scope in which one assigns a value to the variable, unless scope is explicitly declared with global or nonlocal. ?