python中函數的默認參數陷阱問題


其實也不能說是陷阱,只是一個不容易注意到的地方,尤其是有其他java/c++類編程語言經驗的人員,這里涉及到python的一個特點,所以筆者說是陷阱只是一個噱頭而已。

def test(item, buf = []):
	buf.append(buf)
	print buf

非常簡單的一個函數,功能非常簡單,現在看下面的調用代碼

test('younger')
test('shen')

輸出:

['younger']		
['younger', 'shen']

該函數初衷是希望當沒有提供默認的buff參數的時候,建立一個空的列表,然后把一個對象添加到該列表中,並且打印, 但是程序的執行似乎並沒有按照我們的意圖來執行,似乎每個函數都共享了buff,但是我們明明每次都在參數列表中初始化了buff變量,分析如下:

python中的def語句在每次執行的時候都初始化一個函數對象,這個函數對象就是我們要調用的函數,可以把它當成一個一般的對象,只不過這個對象擁有一個可執行的方法和部分屬性,對於參數中提供了初始值的參數,由於python中的函數參數傳遞的是對象,也可以認為是傳地址,只有def的時候初始化一次,然后在調用者和被調用者中都是共享的,所以在 func.func_defaults中只能看到一個默認參數,在該函數對象被初始化的時候就已經存在了。

解決這個問題可以用這個方法

def test(item, buf = None):
	if buf is None:
		buf = []
		buf.append(item)
	print buf

這樣在不給定buf參數的時候可以初始化一次buf,每次都是新的,所以不會出現上面的陷阱,其實這里的None只是占位符而已,用空[]也可以,只不過要需要這樣寫

def test(item, buf = []):
	if len(buf) < 1:
		buf = []
		buf.append(item)
		print buf

這樣也可以解決問題,只是看起開不太好而已。

近期除了使用django進行web開發之外,打算重新開始學習linux和操作系統的東西,近期會制定學習計划開始執行。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM