I came across something today that I considered very odd.
>>> import StringIO>>> def test(thing=StringIO.StringIO()):... thing.write("test")... print thing.getvalue()... >>> test()test>>> test()testtest>>> test()testtesttest>>> test()testtesttesttest>>> test()testtesttesttesttest
Before today I would have read the line
def test(thing=StringIO.StringIO()):
as:
Declare a function which, whose kwargs dictionary, when called has a new
StringIO
by default as the value for the key 'thing', and add it to the current scope.
but from the example I think it's more like:
Declare a function. Construct a dictionary with a new
StringIO
in it. Assign this to the default kwargs of the function and add the function to the current scope.
Is this the correct interpretation? Are there any other gotchas to be aware of for default kwargs?
- 1Are you looking for this?docs.python.org/reference/…S.Lott– S.Lott2011-04-21 15:22:22 +00:00CommentedApr 21, 2011 at 15:22
- What, you mean thebig statement in bold? Heh. Yes.Joe– Joe2011-04-21 15:23:22 +00:00CommentedApr 21, 2011 at 15:23
2 Answers2
Your second definition is perfectly correct. This behavior will happen with any mutable object. The common idiom is to useNone
as a guard.
def test(thing=None): if thing is None: thing = StringIO.StringIO() thing.write("test") print thing.getvalue()
See this answer onPython 2.x gotcha's and landmines for more detail.
1 Comment
Yes, the second interpretation is correct. It's one of the gotchas in Python. It's has been discussed here numerous times. See for example:"Least Astonishment" and the Mutable Default Argument
Comments
Explore related questions
See similar questions with these tags.