Is it possible to write a function in python, which takes an argument a and prints the result of h+a where h is a local variable. Then it should return itself, with h increased by one.
Asked
Active
Viewed 1,353 times
1
-
1But why? You should change the title to emphasize learning about closures -- otherwise you may get a lot of people telling you that `simulating static variables is a waste of time -- python already has them!` Also, they're not called static variables in python. – Matt Fenwick Nov 17 '11 at 22:32
-
i was just curious if it's possible because i wasn't able to create my own solution. and i wasn't sure how to title the question. – Moe Nov 17 '11 at 22:48
2 Answers
5
In python 3, you can do this:
>>> def f(a):
... h = 1
... def inner():
... nonlocal h
... print(a+h)
... h += 1
... return inner
... return inner
...
>>> g = f(3)
>>> g = g()
4
>>> g = g()
5
>>> g = g()
6
>>> g()()()
7
8
9
<function inner at 0xb71bcd6c>
Previous versions required faking it:
>>> def f(a):
... h = [1]
... def inner():
... print a + h[0]
... h[0] += 1
... return inner
... return inner
...
>>> f(3)()()()
4
5
6
<function inner at 0x10041f050>
>>>
(ETA: I guess I misinterpreted part of the question, since it seems you want the function returned by f
(and that returns itself) to take the argument, but that's a trivial change.)

ben w
- 2,490
- 14
- 19
-
2basically, before python3, if you tried to *assign* to h in inner(), "h" is considered local to inner(). So you have two options: (a) assign then use. Then h in inner() shadows the h in f(), and it isn't preserved across calls, and that's not what you want. (b) use then assign. But since it's considered local to inner, you can't use it before assigning it---it's not bound yet. With h = [1], all you're doing in inner is using it---you refer to it, but you never assign to *h itself*. you just assign to h[0]. – ben w Nov 18 '11 at 02:52
2
Yes, you can
def f(a):
def inner(h, a):
print h+a
return lambda (x): inner(h+1, x)
return inner(1, a)
example
g = f(0) # +1
g = g(0) # +2
g = g(0) # +3
f(0) # +1
g(0) # +4
g(0) # +4
prints
1
2
3
1
4
4
Q.E.D.

sehe
- 374,641
- 47
- 450
- 633
-
This isn't incrementing a local variable. You're really only simulating what the poster wants. – ben w Nov 17 '11 at 23:08