def main():
funcs = []
for x in range(10)
def f(x=x):
return x
funcs.append(f)
print([f(x) for f in funcs])
The "x=x" default argument is necessary here. In this example it's just a constant but this trick is often used with mutable defaults.[1] https://github.com/satwikkansal/wtfpython#-beware-of-default...
[2] https://github.com/satwikkansal/wtfpython#-loop-variables-le...
> In this example it's just a constant but this trick is often used with mutable defaults.
Your example doesn't work with mutable defaults. Ironically it falls into the trap the parent comment was referring to!
def main():
funcs = []
arg = []
for x in range(10)
arg.append(x)
def f(arg=arg):
return arg
funcs.append(f)
print(*[f() for f in funcs], sep="\n")
# result: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] printed 10 times
These functions will all return the same 10-element list. Instead you need to use `def f(arg=arg[:])` or `def f(arg=copy(arg))` (after from copy import copy).> print([f(x) for f in funcs])
Just a typo but you meant print([f() for f in funcs])
In one case, the value is a non-mutable int, while in the other it's a mutable list, but in both cases each call to those functions will share the same value for that argument (unless overriden).
No I’m not. Exercise for the reader to figure out why. The key thing here is that you want a mutable variable for each closure, but not shared between loop iterations.
Ah ha! I misread your comment! This was the bit that confused me:
> They're also an escape hatch,
I read this as
> There's also an escape hatch,
So I thought you were saying that the code in your comment was a solution to the problem posted by the original comment. This is why I found your comment so bewildering! I now see that what you were saying that this gotcha (Python evaluates function default arguments, once, at the point of definition) also has a use.
So, I have to say sorry about that. But I also can't help saying your comment could've been phrased a bit less confusingly.
And I was sure that it was cause by a bug in my code, thanks for pointing this out - now I know what caused this
https://github.com/satwikkansal/wtfpython#-beware-of-default...