2010-01-31 135 views
3

我有一些很難理解與類初始化參數是列出
像發生了:Python的__init__參數問題

class A(object): 
    def __init__(self, argument=[]): 
     self.argument = argument[:] 

或:

def __init__(self,argument=None): 
    self.arguments = arguments or [] 

或:

def __init__(self, argument=[]): 
    self.argument = argument 

這是不可能的,因爲每個的默認值對象會指向同一塊內存。我無法真正理解這裏發生了什麼,以及它是如何發生的。

+1

你能描述一下你試圖達到什麼樣的問題嗎?事實上,這不是一個問題。 – 2010-01-31 05:53:33

+0

錯字? s /參數/參數/愚蠢的6字符限制不會讓我編輯它。 – ijk 2013-01-22 01:35:56

回答

4

該列表在定義運行時創建,而不是在執行該方法時創建。

1

我認爲這個問題是有些不清楚,但我從中明白的是,你想知道如何使一個類初始化列表不會使內部對象傳遞給它的同一個,而是一個副本。如果這不是問題,告訴我,我會刪除這個答案。

簡單地說,這裏是它的工作原理是:沒有什麼是存儲在Python中值的名稱。一切都作爲指向Python對象的指針在內部存儲。當你這樣做:

a = [1,2,3] 
b = a 

你不設置b價值a。您正在設置b以引用相同的對象。所以聲明:

a is b 

是真的,因爲名稱引用同一個對象。

a = [1,2,3] 
b = [1,2,3] 
a is b 

這將返回false。原因是現在你已經創建了兩個不同的對象。因此該行:

self.argument = argument[:] 

是製作self.argument副本,以便它不引用同一個對象的(必要的)的方式。

+0

對不起,因爲我的英語不好,我想這就是爲什麼我被人誤解, 你的答案無論如何幫助,但真正的問題是爲什麼在最後一個例子中,每個新的對象沒有初始化者會有相同的列表(相同的對象) 例如,如果我創建不帶參數的類型a的對象b,c和d b,c和d的參數成員將是相同的(共享) – damian 2010-01-31 05:54:56

+0

哦,我現在明白了。是的,這是Python中比較常見的「失誤」之一。谷歌「Python默認參數」,你會看到。做你想做的事情的正確方法是使默認參數爲None,然後對None執行檢查,在那個時候創建​​列表。 – avpx 2010-01-31 05:58:08

+1

好我明白了一切,現在[]定義不是創建每個對象時評估[]。 (就像第一個評論說的,但那一刻我根本就不理解它) 謝謝!這是我第一次使用這個網站,我從來沒有得到如此快速的答案! (其實我從來沒有在論壇上得到任何迴應) – damian 2010-01-31 06:10:43

6

這是一個衆所周知的pythongotcha

基本上,該參數的默認值是在首次定義該方法時創建的,並且由於它是一個可變對象(在本例中爲列表),因此它只是在相同的對象發生更改後再作出反應,並且即使在後續調用的方法。

通常的方法來處理這樣的情況是在你的第二個例子,像對待:

def __init__(self, arguments=None): 
    self.arguments = arguments or [] 

但是如果你想要做的是與所有你的論點,你可以只使用Python的列表argument unpacking

它的工作原理是這樣的:

def my_function(*args): 
    print args 

那麼,你會在你的方法訪問元組傳遞的所有參數。所以,如果你叫你的函數是這樣的:

>>> my_function(1, 2, 3) 

你的輸出看起來像:

(1, 2, 3) 

很酷的事情是,你可以隨時用它在oposite方式,所以,讓我們假設你有一個列表(或元組),並且您想要將列表中的每個項目作爲函數的位置參數傳遞。你應該這樣做:

>>> my_list = [1, 2, 3] 
>>> my_function(*my_list) 

而且,就你的功能而言,它與以前的調用相同。

您應該閱讀documentation that I pointed to以及defining functions上更深入的部分。

+0

謝謝!,有用的信息,我想我開始喜歡python:D – damian 2010-01-31 06:17:31