首先來看問題:
>>> def add_end(l=):
...return l
...>>>
>>> t=add_end()
>>>
>>> t
['end']
>>> t=add_end()
>>> t
['end', 'end']
>>> t=add_end([1])
>>> t
[1, 'end']
>>> t=add_end()
>>> t
['end', 'end', 'end']
>>> t=add_end([1])
>>> t
[1, 'end']
>>> t=add_end()
>>> t
['end', 'end', 'end', 'end']
python函式在定義的時候(只在那個時刻賦值,此後呼叫不再賦值),預設引數l的值就被計算出來了,即,因為預設引數l也是乙個變數,它指向物件,每次呼叫該函式,如果改變了l的內容,則下次呼叫時,預設引數的內容就變了,不再是函式定義時的了
python函式引數對於可變物件,函式內對引數的改變會影響到原始物件;對於不可變物件,函式內對引數的改變不會影響到原始引數。原因在於:
1、可變物件,引數改變的是可變物件,其內容可以被修改。
2、不可變物件,改變的是函式內變數的指向物件。
更明顯的例子:可以看出初始化時機
import datetime as dt
deflog_time
(message, time=dt.datetime.now()):
print(": ".format(time.isoformat(), message))
每次我們呼叫log_time()時都期望它能夠正確提供當前時間。悲劇的是並沒有成功:預設引數在定義時求值(比如說當你首次匯入模組時),呼叫的結果如下
>>> log_time("message 1")
2015-02-10t21:20:32.998647: message 1
>>> log_time("message 2")
2015-02-10t21:20:32.998647: message 2
>>> log_time("message 3")
2015-02-10t21:20:32.998647: message 3
def
add_end
(l=none):
if l is
none:
l =
return l
現在,無論呼叫多少次,都不會有問題。
none 是不可變物件,每次一賦值為時,他指向的引用就會發生改變,輸出的結果也是改變後的引用內容,但再一次呼叫l還是之前的引用(none)
所以,定義預設引數要牢記一點:預設引數必須指向不變物件!
可變物件與不可變物件
python 預設引數 Python預設引數有坑?
最近有小夥伴在面試中遇到了 關於函式預設引數的坑 的題目,少數夥伴對此問題理得不是太清楚,今天匯智妹請到匯智動力高階教師鄧老師為大家詳細講解一下,幫助不太清楚的小夥伴清晰的梳理一遍。鄧老師本次主要從以下三點來講解 什麼是預設引數?函式預設引數的坑是什麼?函式預設引數為什麼會有坑?一 什麼是預設引數 ...
Python預設引數陷阱問題
def fun a,l print l fun hhh fun mmmm fun xingkd python中的def語句在每次執行的時候都初始化乙個函式物件,這個函式物件就是我們要呼叫的函式,可以把它當成乙個一般的物件,只不過這個物件擁有乙個可執行的方法和部分屬性,對於引數中提供了初始值的引數,由...
預設引數問題
如果在呼叫乙個函式時,沒有傳遞預設引數,則函式內的預設引數是對函式的預設引數屬性 defaults 的引用,自己的理解,讓我聯想到賦值,淺拷貝,這裡是淺拷貝,改變args的值,不會影響 defaults 0 的值,但是改變args子物件的值,會同時讓 defaults 0 的子物件發生變化,即 de...