Home >Backend Development >Python Tutorial >Need to be careful when the default value of Python function parameters is a mutable object
I saw that variable objects are passed to the default values of Python function parameters to speed up the recursion of the Fibonacci function. The code is as follows:
def fib(n, cache={0: 0, 1: 1}): if n not in cache: cache[n] = fib(n - 1) + fib(n - 2) return cache[n]
Isn’t it strange that this can be done? The speed is really very fast, and the running results are as follows:
## However, I advise you not to do this, and the IDE will also prompt you that it is bad to do so: This is because everything is an object, and Python functions are also objects. The default value of the parameter is the attribute of the object. The default value of the parameter is already bound to the function during the compilation phase. If it is Variable objects, the default values of Python function parameters will be stored and shared by all callers. In other words, if the default value of a function parameter is a variable object, such as List or Dict, caller A modified it. Then caller B will see the modified result of A when calling. Such a mode often produces unexpected results, such as the fib algorithm above, but most of them are bugs. You can take a look at this simple code:def func(n, li = []): for i in range(n): li.append(i) print(l) func(2) # [0,1] func(3,l=[1,2]) # [1,2,0,1,2] func(2) # [0,1]You can estimate the output of this code first. If it is the same as the one in the comments, then you are wrong. The correct result is:
[0, 1] [1, 2, 0, 1, 2] [0, 1, 0, 1]You may wonder why the last func(2) is like this. Don’t worry, let’s print(id(li)) to debug it:
def func(n, li = []): print(id(li)) for i in range(n): li.append(i) print(li) func(2) func(3,li=[1,2]) func(2)The results are as follows :
140670243756736 [0, 1] 140670265684928 [1, 2, 0, 1, 2] 140670243756736 [0, 1, 0, 1]Have you noticed that the ids of the first func(2) and the second func(2) are the same, indicating that they use the same li, which is the default value of the parameter. It is the logic of a mutable object, which is shared by all callers. If you want to delve into why Python is designed this way, you can go to http://cenalulu.github.io/python/default-mutable-arguments/How to avoid it? The best way is not to use mutable objects as function default values. If you have to use it this way, here is a solution:
def generate_new_list_with(my_list=None, element=None): if my_list is None: my_list = [] my_list.append(element) return my_listIn this way, if the default value of my_list is always []. FinallyI think the implementation of the fib function may impress you, but please note that such usage is very dangerous and cannot be used in your own code .
The above is the detailed content of Need to be careful when the default value of Python function parameters is a mutable object. For more information, please follow other related articles on the PHP Chinese website!