Skip to content

[Python] The Problem with Functions Using Mutable Objects as Default Parameters

Last Updated on 2022-07-28 by Clay

When we create a python function, sometimes we pass some parameters for it, even set the default value for the parameters, let the function can work if we have no pass any parameter.

However, if we use mutable objects to be default parameter (such as List or Dictionary), there is a very terrible problem wait for us.


The Error Example

The following is a classical error if we set the mutable object to be function default parameter.

def foo(arr=[]):
    arr.append(100)

    return arr


def main():
    print(foo())
    print(foo())
    print(foo())


if __name__ == "__main__":
    main()


I want to no matter how many times the foo() function run, I usually can get the [100] return value, likes:

理想中我希望不管執行了 foo() 函式多少次,我始終都能得到 [100] 這樣的回傳值,也就是說我們希望得到:

[100]
[100]
[100]


But in fact, we will get the following returns:

[100]
[100, 100]
[100, 100, 100]


Why?

To put it simply, if you read the official document (you can find the link in the "References"), Our understanding of def keyword is that will create a function object, and initialize it, so no matter how many times we call the function, the function object will be the same object.

But if we set a mutable object, something is different. If we call the function, we always operate the same mutable variable!


Solution

The solution is very naive: Do not set the mutable object to be default parameter. For example, if we want to do the following function effect:

def foo(arr=None):
    if arr is None:
        arr = []

    arr.append(100)

    return arr


def main():
    print(foo())
    print(foo())
    print(foo())


if __name__ == "__main__":
    main()


Output:

[100]
[100]
[100]


We can set None to be the default parameter, and initialize it in the function block.


References


Read More

Tags:

Leave a Reply