No, redefining square()
every time is doing what you want, which you can check by printing the contents of dispatcher
: all the functions in it will have different id's as desired.
The problem is that you're creating a closure so when you call any of the functions stored in dispatcher
they are accessing the latest value of i
, rather than using the value that i
had when they were defined.
Robᵩ has shown one way around that, by passing i
as an arg to square()
; here's another way: using another closure which takes i
as an arg so it can preserve it for the squaring function it makes.
def dispatcher_create():
dispatcher = {}
def make_square(j):
def square():
return j**2
return square
for i in range(5):
dispatcher[i] = make_square(i)
return dispatcher
dd = dispatcher_create()
print dd
for j in range(5):
print dd[j]()
typical output
{0: <function square at 0xb73a0a3c>, 1: <function square at 0xb73a0dbc>, 2: <function square at 0xb73a0d84>, 3: <function square at 0xb73a5534>, 4: <function square at 0xb73a517c>}
0
1
4
9
16
Robᵩ's version is a little simpler, but this version has the advantage that the functions in dispatcher
have the desired argument signature, i.e., they take no argument, whereas Robᵩ's functions take a single argument with a default value that you can over-ride.
FWIW, you could use i
instead of j
as the parameter for make_square()
, since it's just a local variable to make_square()
. OTOH, using i
there shadows the i
in the outer scope, and I feel that using j
is slightly less confusing.