2013-01-21 26 views
0

可能重複:
「Least Astonishment」 in Python: The Mutable Default Argument無法初始化參數列表中的字典?

我有奇怪的行爲有以下幾點: -

def set_diary_time_data(day_str, x={}): 
    # Dict for template in html 
    print 'Set diary time data' 
    print x 

我把這種功能包含: -

x = heading_queries.set_diary_time_data(day_str) 

因此,字典x不作爲參數傳遞,因此它應該被初始化爲{}

但是,重複調用此函數時,x中的值將保留在先前的調用中。 這是在django中,當用戶登錄時調用,前一個用戶的詳細信息保留在x中。 (X不被設置爲全局變量。)

我可以通過改變函數

def set_diary_time_data(day_str, x=None): 
    if not x: x = {} 

(Python 2.7版)

+0

作爲旁白,您應該使用:'if x is None:x = {}' –

回答

0

在Python中,參數和默認值被評估一次克服這個問題,並不是每次調用。這可能會導致一些令人驚訝的行爲。

例如:

def foo(names=[ "foo", "bar", "hello" ]) 
    names.append("whatever") 
    print names 

foo() 
foo() 

生成的輸出:

[ "foo", "bar", "hello", "whatever" ] 
[ "foo", "bar", "hello", "whatever", "whatever"] 

經驗法則,因此應避免任何可變對象作爲參數的默認值。

+0

Thankland Lowestland:關閉此查詢,此處的標題比選擇「最小驚訝」更容易理解 – jimscafe

+0

@jimscafe其實並不重要,首選是避免重複頁面,而是專注於改進問題及其標題。國際海事組織的兩個標題都是有效的,欺騙指出問題的根源,你提到了其中一種可能的表現形式。 (對於合併的問題,我仍然認爲這個問題更好,只是因爲這個問題可以通過幾種方式表現出來,可以用不同的表述來表達。) – millimoose