Still confused about mutable default parameter value “gotcha” in Python

試著忘記壹切 提交于 2021-02-16 05:05:38

问题


I understand that one should not use mutable default parameter value in Python (with some exceptions) because this value is evaluated and stored only once when the function is defined, and not each time the function is later called.

My understanding of that is this (using the example below; please excuse my imprecise language as I'm just a beginner in Python programming, who's stuck at the Function chapter of my textbook because of this):

def f(x = [1, 2, 3]):
    x.append(4)
    print(x)

f()
f()

1) The function f is defined, and x (local variable in f) assumes the default variable of [1, 2, 3] (even before the function is called)

2) When f() is called, x is still [1, 2, 3] due to no argument passed to it, and x continues having its default value

3) x is modified in place with append, becomes [1, 2, 3, 4], and is printed as such

However, this is where my confusion arises. I'd assume that:

4) When f ends, x is destroyed (in the stack or whatever you'd call it) and is no longer associated with the list object [1, 2, 3, 4]**

5) The list object [1, 2, 3, 4] is reclaimed since there's no variable that refers to it anymore

Therefore,

6) When f() is called the second time, I'd expect Python to output an error since x now no longer has a value associated with it. In other words, how can Python reuse the default value from the last evaluation when it's been reclaimed/destroyed?

Appreciate all your help and explanation!

** this understanding I got from Ned Batchelder's page on variable name assignment (see below)


回答1:


While it may seems to you that at the end of the execution x, the default value, is disposed, it is not.

In fact, Python has a global namespace with all the names available for you to use (built-in functions, classes and functions you import or define).

The content of this namespace is made of objects. Function are objects too.

As a test, if you try this in a script or in the python command line, you will see what I mean:

def f(x = [1, 2, 3]):
    x.append(4)
    print(x)
print dir(f)

you will see the object nature of the function f. As an objects, the default values are referenced in an attribute, f.func_defaults, therefore they are always available and if mutable they retain the changes, giving you side effects with you may not want.

EDIT: in python 3 the attribute has been replaced by f.__defaults__




回答2:


There are two references to the list in your case, one is store in the background of the function as the default value to the argument x.

When the function is called without x, a new reference to the same list is created as the local variable x. Then you append to the list via the second reference. And after the call, the second reference is garbage collected. The first reference still points to the same list, which has one element more now.

Or in short: there is only one list all the time.



来源:https://stackoverflow.com/questions/46402055/still-confused-about-mutable-default-parameter-value-gotcha-in-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!