On Fri, 15 May 2015 04:06 am, Billy Earney wrote: > Hello friends: > > I saw the following example at > http://nafiulis.me/potential-pythonic-pitfalls.html#using-mutable-default-arguments > and > did not believe the output produced and had to try it for myself.... > > def foo(a,b,c=[]): > c.append(a) > c.append(b) > print(c) > > foo(1,1) > foo(1,1) > foo(1,1) > > produces: > [1, 1] > [1, 1, 1, 1] > [1, 1, 1, 1, 1, 1] > > One would expect the following output: > [1, 1] > [1, 1] > [1, 1]
Really? Why would you expect that? The *body* of the function is executed every time the function runs. The *definition* of the function is executed once, and only once, when the function is first defined. Setting the default value of a parameter is part of the definition, not the body, and so it happens once only, not every time. It truly would be surprising if the function recalculated the default value every time. Since the default value for c is a list, you are mutating the *same list* each time. This question comes up repeatedly. It's a FAQ, and the most recent time was less than a week ago: https://mail.python.org/pipermail/python-list/2015-May/703043.html See, in particular, my response: https://mail.python.org/pipermail/python-list/2015-May/703065.html > Doesn't this valid the zen of python: "Explicit is better than implicit." > ? I think you mean "invalidate". No, this has nothing to do with explicitness or implicitness. Regardless of whether Python uses "early binding" or "late binding" of the default parameter, it is still equally explicit. The problem occurs because people assume one binding model (which is entirely inconsistent with everything else in Python) and get it wrong: people assume that function defaults are late binding, but they are not. -- Steven -- https://mail.python.org/mailman/listinfo/python-list