2

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 newStringIO 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 newStringIO 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?

askedApr 21, 2011 at 15:18
Joe's user avatar
2
  • 1
    Are you looking for this?docs.python.org/reference/…CommentedApr 21, 2011 at 15:22
  • What, you mean thebig statement in bold? Heh. Yes.CommentedApr 21, 2011 at 15:23

2 Answers2

4

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.

answeredApr 21, 2011 at 15:20
Daenyth's user avatar
Sign up to request clarification or add additional context in comments.

1 Comment

Yes that's exactly what I did. Just thought I'd check that I was doing it for the right reason.
2

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

answeredApr 21, 2011 at 15:25
vartec's user avatar

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.