4 ms·
You're talking about something different. The parent comment is about mutable default arguments are shared between all calls to that function [1], but you seem
by quietbritishjim 6y ago
You're talking about something different. The parent comment is about mutable default arguments are shared between all calls to that function [1], but you seem to be talking about functions defined in for loops all sharing a reference to the same variable [2].
[1] https://github.com/satwikkansal/wtfpython#-beware-of-default-mutable-arguments https://github.com/satwikkansal/wtfpython#-beware-of-default...
[2] https://github.com/satwikkansal/wtfpython#-loop-variables-leaking-out 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])
- tcard 6y agoThese are two manifestations of the same feature: function arguments's default values are evaluated when the function is defined. 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).
- klodolph 6y ago> You're talking about something different. 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.
- quietbritishjim 6y ago[Edit: deleted my original reply here. I had ended in "Are you sure you didn't misread the original comment?"] 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.