Need to be careful when the default value of Python function parameters is a mutable object

WBOY
Release: 2023-04-22 13:37:07
forward
1224 people have browsed it

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]
Copy after login

Isn’t it strange that this can be done? The speed is really very fast, and the running results are as follows:

小心此坑:Python 函数参数的默认值是可变对象

## However, I advise you not to do this, and the IDE will also prompt you that it is bad to do so:

小心此坑:Python 函数参数的默认值是可变对象

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]
Copy after login

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]
Copy after login

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)
Copy after login

The results are as follows :

140670243756736
[0, 1]
140670265684928
[1, 2, 0, 1, 2]
140670243756736
[0, 1, 0, 1]
Copy after login

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_list
Copy after login
In this way, if the default value of my_list is always [].

Finally

I 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!

Related labels:
source:51cto.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template