2010-02-10 74 views
0

我有一個奇怪的問題。我知道在Python中,kwargs遵循參數,所以我檢查了它,這不是問題。這是什麼問題是這樣的:兩個關鍵字參數的位置交換拋出錯誤

精細:

def __init__(self, sample_rate, label=u"", data=[]):

類型錯誤:__init__()得到了關鍵字參數 '數據' 多個值:

def __init__(self, sample_rate, data=[], label=u""):

拋出的呼叫線路錯誤看起來像這樣:

def __getslice__(self, start, stop): 
    return Channel(self.sample_rate, self.label, data=list.__getslice__(self,start,stop)) 

的完整代碼:

class Channel(list): 
    sample_rate = 0 

    def __init__(self, sample_rate, data=[], label=u""): 
    list.__init__(self,data) 
    self.sample_rate = sample_rate 
    self.label = label 

    @property 
    def nyquist_rate(self): 
     return float(self.sample_rate)/2.0 

    def __getslice__(self, start, stop): 
     return Channel(self.sample_rate, self.label, data=list.__getslice__(self,start,stop)) 

謝謝!

回答

4

在第二個版本(def __init__(self, sample_rate, data=[], label=u""):),第二個位置參數(調用時,這意味着不包括self)是data,但在__getslice__,第二你通過的論點是label。因此,您應該保持標籤作爲第二個參數,或改變功能調用此:

return Channel(self.sample_rate, label=self.label, data=list.__getslice__(self,start,stop)) 
+0

Bah!一個很好的例子,說明爲什麼我不應該在早上4點編碼。謝謝所有人,因爲我很難理解我的愚蠢錯誤。 – SapphireSun 2010-02-10 10:19:10

4

您與

Channel(self.sample_rate, self.label, data=list.__getslice__(self,start,stop)) 

注意,第二個參數沒有關鍵字,所以解釋假定這是data參數(因爲這是它們在功能定義的順序)調用的代碼。如果你添加label=它應該解決它。

但是,您的代碼中有一個更重要的錯誤:請勿將[]用作默認值。原因是這個代碼是在函數定義時評估的。每次你撥打這個沒有data參數的代碼,,你會得到和默認值相同的列表。在第一次之後它可能不會是空的!所有可變數據類型都是如此。正確的方法是使用None作爲默認值,並且在函數(每次運行的代碼)內初始化一個新的[],如果參數值爲無。 (此戈查也由大衛Goodger很好地解釋,在Default Parameter Values

2

的問題是,在你的調用代碼,你有兩個位置參數:

return Channel(self.sample_rate, self.label, data=list.__getslice__(self,start,stop)) 
#    sample_rate (pos) data (pos) data (kw) 

在Python 2.x,函數定義中的位置和關鍵字參數沒有區別。當一個函數被調用時,函數調用的位置參數被用來填充從左到右的參數,然後所有的關鍵字參數都被綁定。在你的情況下,data被位置和關鍵字參數綁定。它在另一種情況下工作,因爲第二個位置參數用於label,並且data僅獲取關鍵字參數。