0

Possible Duplicate:
“Least Astonishment” in Python: The Mutable Default Argument

I have strange behavior with the following :-

def set_diary_time_data(day_str, x={}):
    # Dict for template in html
    print 'Set diary time data'
    print x

I call this function with :-

    x = heading_queries.set_diary_time_data(day_str)

So the dictionary x is not passed as a parameter so it should be initialized to {}

However on repeated calls to this function the values placed in x are retained from the earlier call. This is in django and is called when a user logs in, the details of the previous user are retained in x. (x is not set as a global variable.)

I can overcome this by changing the function to

def set_diary_time_data(day_str, x=None):
    if not x: x = {}

(Python 2.7)

Community
  • 1
  • 1
jimscafe
  • 1,081
  • 2
  • 14
  • 24

1 Answers1

0

In python, arguments and defaults are evaluated once, and not on every invocation. This can lead to some surprising behaviour.

For example:

def foo( names=[ "foo", "bar", "hello" ] )
  names.append( "whatever" )
  print names

foo()
foo()

Produces an output:

[ "foo", "bar", "hello", "whatever" ]
[ "foo", "bar", "hello", "whatever", "whatever"]

The rule of thumb, therefore should be to avoid any mutable objects as argument defaults.

fallenland
  • 525
  • 2
  • 6
  • Thank you fallenland : regards closing this query, the title here is easier to understand than the option presented "Least Astonishment" – jimscafe Jan 21 '13 at 03:08
  • @jimscafe Doesn't really matter, the preference is to avoid duplicating pages, and instead focus on improving questions and their titles. IMO both the titles are valid, the dupe names the root cause of the problem, yours mentions one of the possible manifestations. (For the merged question I still think the dupe's is better, simply because this problem can manifest in several ways that can be phrased differently.) – millimoose Jan 21 '13 at 03:54