成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

小心此坑:Python 函數(shù)參數(shù)的默認(rèn)值是可變對象

開發(fā) 前端
Python 函數(shù)也是對象,參數(shù)的默認(rèn)值就是對象的屬性,在編譯階段參數(shù)的默認(rèn)值就已經(jīng)綁定到該函數(shù),如果是可變對象,Python 函數(shù)參數(shù)的默認(rèn)值在會被存儲,并被所有的調(diào)用者共享,也就是說,一個函數(shù)的參數(shù)默認(rèn)值如果是一個可變對象。

看到了有給 Python 函數(shù)參數(shù)的默認(rèn)值傳遞可變對象,以此來加快斐波那契函數(shù)的遞歸速度,代碼如下:

def fib(n, cache={0: 0, 1: 1}):
if n not in cache:
cache[n] = fib(n - 1) + fib(n - 2)
return cache[n]

是不是很新奇,居然可以這樣,速度真的非常快,運行結(jié)果如下:

圖片

不過,我勸你不要這樣做,而且 IDE 也會提示你這樣做很不好:

圖片

這是因為,萬物皆對象,Python 函數(shù)也是對象,參數(shù)的默認(rèn)值就是對象的屬性,在編譯階段參數(shù)的默認(rèn)值就已經(jīng)綁定到該函數(shù),如果是可變對象,Python 函數(shù)參數(shù)的默認(rèn)值在會被存儲,并被所有的調(diào)用者共享,也就是說,一個函數(shù)的參數(shù)默認(rèn)值如果是一個可變對象,例如 List、Dict,調(diào)用者 A 修改了它,那么之后調(diào)用者 B 在調(diào)用的時候看到的就是 A 修改后的結(jié)果,這樣的模式往往會產(chǎn)生意想不到的結(jié)果,比如上面 fib 的算法,但更多的是 bug。

可以看下這段簡單的代碼:

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]

你可以先估算一下這段代碼的輸出,如果和注釋中的一樣,那你就錯了。正確的結(jié)果是:

[0, 1]
[1, 2, 0, 1, 2]
[0, 1, 0, 1]

你可能會覺得,最后一個 func(2) 怎么是這樣,不急,我們 print(id(li)) 調(diào)試一下:

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)

結(jié)果如下:

140670243756736
[0, 1]
140670265684928
[1, 2, 0, 1, 2]
140670243756736
[0, 1, 0, 1]

有沒有發(fā)現(xiàn),第一個 func(2) 和第二個 func(2) 的 id 是一樣的,說明它們用到的是 li 是同一個,這就參數(shù)的默認(rèn)值是可變對象的邏輯,對于所有的調(diào)用者來講,是共享的。

如果要深入研究 Python 為什么這么設(shè)計,可以移步 http://cenalulu.github.io/python/default-mutable-arguments/

如何避免?

最好的方式是不要使用可變對象作為函數(shù)默認(rèn)值。如果非要這么用的話,下面是一種解決方案:

def generate_new_list_with(my_list=None, element=None):
if my_list is None:
my_list = []
my_list.append(element)
return my_list

這樣,如果 my_list 默認(rèn)值永遠(yuǎn)都是 []。

最后

我想那個 fib 函數(shù)的實現(xiàn)可能會讓你印象深刻,不過請注意,這樣的用法非常危險,不可用于自己的代碼中。

責(zé)任編輯:武曉燕 來源: Python七號
相關(guān)推薦

2020-02-17 10:34:04

箭頭函數(shù)開發(fā) JavaScript

2024-06-27 09:17:33

2010-09-28 10:23:36

SQL修改字段

2012-08-01 09:50:11

交互設(shè)計UI設(shè)計

2023-12-14 10:23:01

C++模板函數(shù)

2021-02-25 13:40:17

MySQL數(shù)據(jù)庫默認(rèn)值

2024-04-08 07:58:11

Python數(shù)據(jù)類型字符串

2022-06-21 08:13:34

MySQL查詢數(shù)據(jù)庫

2025-02-06 13:23:09

C++函數(shù)參數(shù)

2010-11-23 16:49:42

MySQL設(shè)置當(dāng)前時間

2022-03-21 19:24:15

Objects方法false

2010-07-15 10:37:15

SQL Server默

2010-10-22 16:56:35

sql server刪

2011-08-01 17:11:43

Objective-C 函數(shù)

2009-12-24 16:03:16

ADO.NET部署

2010-09-28 10:35:58

SQL字段默認(rèn)值

2010-09-28 15:24:43

sql語句

2009-12-18 17:07:14

2010-09-07 16:05:23

SQL語句刪除

2010-09-03 10:52:10

SQL刪除
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 日本在线免费视频 | 欧美韩一区二区 | 国产精品视频一二三区 | 国产精品久久久久久久久久久久午夜片 | 亚洲精品亚洲人成人网 | 日韩在线中文字幕 | 日韩欧美在线观看 | 国产精品久久久久一区二区三区 | 九九热在线免费视频 | a级免费黄色片 | 亚洲视频一区二区三区 | 欧美成人精品在线 | 成年人视频免费在线观看 | 99视频在线| 日韩av一区二区在线观看 | 成人一区在线观看 | 国产综合精品一区二区三区 | 91精品国产91久久久久久吃药 | 日韩h | 亚洲精品一区二区三区蜜桃久 | 色永久 | 天天干天天干 | 欧美激情久久久 | 欧美性video| 国产在线一区二区 | 欧美日韩福利视频 | 成人毛片在线观看 | 午夜男人视频 | 久久久91| 欧美精品一区在线 | 91在线精品秘密一区二区 | 国产高清av免费观看 | 精品国产久 | 国产一区二区三区在线 | 欧美成人一级 | 黄色一级片视频 | 欧美精品中文字幕久久二区 | 午夜ww | 日本中文字幕视频 | 97热在线| 久久久久一区二区三区 |