python並不簡單 FAQ-0x01
阿新 • • 發佈:2018-12-14
Question 0x01
看看下面的函式會輸出什麼:
In [157]: def f(x, l=[]):
...: for i in range(x):
...: l.append(i*i)
...: print(l)
...:
In [158]: f(2)
In [159]: f(3,[3,2,1])
In [160]: f(3)
In [161]: f(3)
先仔細想一下,再看下面的答案。
Answer 0x01
In [158]: f(2) [0, 1] In [159]: f(3,[3,2,1]) [3, 2, 1, 0, 1, 4] In [160]: f(3) [0, 1, 0, 1, 4] In [161]: f(3) [0, 1, 0, 1, 4, 0, 1, 4]
第一二個函式執行結果就不說了,大家可能在第三四個結果上感到很奇怪。
大家想到的結果可能是[0, 1, 4]
和[0, 1, 4]
,但實際結果是[0, 1, 0, 1, 4]
和[0, 1, 0, 1, 0, 1, 4]
,原因就是f
函式中的預設引數l
是可變型別。
在第一次呼叫f
即f(2)
時,l
的預設值[]
已經被改變成了[0, 1]
(相當於預設引數已經被修改了)。
在執行f(3,[3,2,1])
時,l
指向了新的引數[3,2,1]
,但是之前被修改過的預設引數[0,1]
仍然存在(但是[]
不存在了)。
於是,在執行第一個f(3)
時,預設引數l
指向了[0,1]
,並在此基礎上添加了0, 1, 4
,因此得到結果為[0, 1, 0, 1, 0, 1, 4]
小結:
不要輕易使用可變物件(列表,集合,字典)作為預設引數使用,除非你知道你在做什麼。