1

i have a code like this example code:

default_var = "abc"

def set_default_var():
    global default_var
    default_var = "something different"

def ex_func(var1="", var2="", var3=default_var):
    print(var3)

set_default_var()
ex_func()
>>>abc

As I set var3 to default_var in the parameterlist, I expect it to have the value "something different", when I call the function without specifying var3. However, the print shows me "abc". Even during debugging, the debugger shows me that default_var is set to "something different", but var3 is not. Is this a bug, or a very unexpected feature?

Thank you!

MichaelJanz
  • 1,775
  • 2
  • 8
  • 23
  • This behaviour occurs on python 3.8.5 for reproduction purpose – MichaelJanz Mar 15 '21 at 09:55
  • 3
    Default values for functions are evaluated at definition time: https://stackoverflow.com/q/1651154/2237151 – Pietro Mar 15 '21 at 09:58
  • 1
    The default value for `var3` is whatever value the identifier `default_var` referenced *when it was evaluated*. You can see it's `__defaults__` are `('', '', 'abc')`, not `('', '', default_var)`. – jonrsharpe Mar 15 '21 at 09:58
  • Thank you. I find it pretty odd, that the value is not evaluated during runtime, but perhaps its a performance thing. Doing this for all kind of parameters of function when its called, would decrease performance alot. – MichaelJanz Mar 15 '21 at 10:14

1 Answers1

1

The default value is evaluated and stored once when the function is defined. It is not re-checked each time the function is called. This will work as you expect:

default_var = "abc"

def set_default_var():
    global default_var
    default_var = "something different"

def ex_func(var1="", var2="", var3=None):
    if var3 == None:
        var3 = default_var
    print(var3)

set_default_var()
ex_func()
Matthias Fripp
  • 17,670
  • 5
  • 28
  • 45
  • Yes I solved it myself that way, thank you. I find it pretty odd, that the default value is only evaluated at definition time. I had expected otherwise – MichaelJanz Mar 15 '21 at 10:13
  • 1
    Yeah, this is easy to get wrong. A _lot_ of people use a mutable type as the default value (e.g., an empty list), then do things in the function that alter its value, and then are surprised when those changes persist to the next function call. I think the way to think about this is that the `def` statement itself is executable code (that has the effect of defining the function), and the default values are evaluated once when the `def` runs, then get tucked away into the function definition. – Matthias Fripp Mar 15 '21 at 22:46
  • This is a more complete explanation of the perspective I suggested: https://stackoverflow.com/a/1651270/3830997 – Matthias Fripp Mar 15 '21 at 22:56
  • Thank you for that dive, that sound plausible. I come from C#, where this is no issue at all as far as I know, therefore I expected it otherwise – MichaelJanz Mar 16 '21 at 09:27