Ask yourself when np.zeros(1)
is called in both cases. Alternatively, run this code:
def printingFn():
print("printingFn")
return 42
def func1(x = printingFn()):
print("func1")
def func2(x = None):
if x is None: x = printingFn()
print("func2")
func1()
func1()
func1()
print()
func2()
func2()
func2()
You'll see that only one call is made to printingFn
in the func1
sequence, because the default argument is calculated when the function is defined, not every time it is called:
printingFn
func1
func1
func1
printingFn
func2
printingFn
func2
printingFn
func2
That's also true of the func2
sequence, in that the default argument of None
is evaluated at function definition. However, the code that calls printingFn
, since the argument is None
, happens on each call.
What that means in your case is that the good_function
variant of x
is being created freshly every time the function is called. The bad_function
variant is hanging around so maintains the changes made when you assign something to x[0]
.