0

I was working on a function at work and ran into a variable scoping issue that I'm not sure I fully understand. I have written an example below that replicates the behaviour. Why is it that when I run this function consecutively key-value pairs from previous calls are present in the output?

For reference I'm working with python 3.8.8

def scoping_test(x={}, new_things=[]):
   y = x
   y.update({thing: 'test' for thing in new_things})
   return y

Result after running consecutively.

scoping_test(new_things=['thing1'])
{'thing1': 'test'}

scoping_test(new_things=['thing2'])
{'thing1': 'test', 'thing2': 'test'}

The problem goes away if I explicitly make a copy of the dictionary parameter.

x = dictionary.copy()

I would have expected the function to create a new empty variable x each time the function is called and y is just a reference to x. How is y referencing data from a previous function call?

recursive
  • 1
  • 1
  • You are talking about *objects*. Variables are just names that refer to objects. Default arguments in Python are evaluated once, when the function is defined. You re-use the same object each time the default value is provided. This is often surprising behavior for people learning python. – juanpa.arrivillaga Feb 01 '22 at 07:01
  • I didn't know that thanks so that means the object x is created once when it's defined then because y is just a reference to x, the update call is adding data to x which is then accessed on any subsequent calls? What would happen if the user provided a value to x on a subsequent run? – recursive Feb 01 '22 at 07:12
  • I'm not sure what you are asking, if a user provides a value when the function is called, then that is the value the parameter will reference. – juanpa.arrivillaga Feb 01 '22 at 07:30
  • Also https://stackoverflow.com/q/1132941/4046632 – buran Feb 01 '22 at 08:29

0 Answers0