On Fri, May 8, 2015 at 9:59 PM, Michael Welle <mwe012...@gmx.net> wrote: > Hello, > > assume the following function definition: > > def bar(foo = []): > print("foo: %s" % foo) > foo.append("foo") > > It doesn't work like one would expect (or as I would expect ;-)). As I > understand it the assignment of the empty list to the optional parameter > foo take place when the function object is created, not when it is > called. I think from the perspective of a user this is very strange. > Anyways, what would be a good idiom to get the desired behaviour?
I'm not sure what the desired behaviour _is_, given that you're not doing anything with the list after appending to it. But argument defaults are evaluated when the function's defined. It's basically like this: DEFAULT_FOO = [] def bar(foo | nothing): if no argument passed: foo = DEFAULT_FOO print("foo: %s" % foo) foo.append("foo") There are times when this is incredibly useful, but if you don't want this behaviour, the most common idiom is this: def bar(foo=None): if foo is None: foo = [] print("foo: %s" % foo) foo.append("foo") As an example of this, a project I'm involved in had a transition function which could work in one of two modes: 1) Transition one file into another 2) Transition one file into another, then that into a third, then a fourth, etc In order to maintain state cleanly, a dictionary was passed in, which provided a "previous position" marker, which could then be updated. For the first form, though, all I needed to do was give it an empty dictionary, which would then be discarded. So the function went something like this: def transition(from, to, state=None): if not state: state={"cursor": 0} # ... state["cursor"] = last_position (I can't easily show you the code; subsequent edits meant that the first case actually wanted to retrieve the cursor position, so it now always has a state dict, and has no default argument. But this is still a valid concept.) Both idioms are very common, and you need to decide whether you want a single mutable default, or a None default that gets replaced by a brand new dict/list/etc every time. Just remember that the construction of a new list is quite different from the assignment of a pre-existing list to a new name. ChrisA -- https://mail.python.org/mailman/listinfo/python-list