2012-11-11 17 views
3

我正在嘗試編寫一個需要3個關鍵字參數的類方法。我之前使用過關鍵字參數,但似乎無法讓它在我的課程中發揮作用。下面的代碼:類方法中的Python關鍵字參數

def gamesplayed(self, team = None, startyear = self._firstseason, 
       endyear = self._lastseason): 

    totalGames = 0 

    for i in self._seasons: 
     if((i.getTeam() == team or team == "null") and 
      i.getYear() >= startyear and i.getYear() <= endyear): 

      totalGames += i .getGames() 

    return totalGames 

產生錯誤:

NameError: name 'self' is not defined

如果我參加了關鍵字參數,讓他們簡單的位置的,它工作正常。因此我不確定我的問題在哪裏。預先感謝您的幫助。

回答

5
def gamesplayed(self, team = None, startyear = self._firstseason, endyear = self._lastseason): 

在您嘗試使用self引用實例變量的函數聲明。然而,這並不工作,爲self僅僅是它獲取到超過了當前實例的引用函數的第一個參數變量名。因此,self尤其不是總是指向當前實例(不像this關鍵字其他語言)。這也意味着該變量在函數聲明期間還沒有定義。

你應該做的是簡單地預設這些參數與None,並預設這些值在函數體內的這種情況下。這也允許用戶實際地將值分析給導致默認值的方法,而無需實際訪問類中某處的值。

+0

謝謝您的深入解釋。它使一切變得更加清晰。 –

+0

正如右下方指出的那樣,需要注意的是,None還沒有被用作用戶可以傳遞的有效值,例如在這個代碼中,如果None不是指不限制。 –

-1

你不能指self這樣。我不知道在關鍵字參數的默認值中引用self的方法。您可以改爲使用佔位符,並在函數體中設置默認值。

_placeholder = object() 

def gamesplayed(self, team=None, startyear=_placeholder, 
       endyear=_placeholder): 
    if startyear is _placeholder: 
     startyear = self._firstseason 
    if endyear is _placeholder: 
     endyear = self. _lastseason 

    # normal code here 
+3

爲什麼不只是'startyear = None'? –

+0

@NedBatchelder'無'可能是'startyear'或'endyear'的有效值。 – rightfold

+0

@Aardvark Ned Batchelder的建議更具慣用性(fww Ned是一個着名的[Python blogging badass](http://nedbatchelder.com/),我認爲他的問題有很多優點)。你的構造存在這樣的問題,即'_placeholder'只是在模塊構建時才定義的,所以它往往會造成令人困惑的語義,而這些語義違背了人們的期望。 – mvanveen

2

關鍵字參數的默認值在模塊構建時綁定,而不是在類實例構造時綁定。這就是爲什麼self未在此上下文中定義的原因。

關於默認值同樣的事實可以創造各種各樣的問題你想有一個關鍵字參數,其中默認值更新一次函數被調用時的任何時間。當你運行這個程序時,你會發現你期望更新的默認值總是被設置爲模塊初次初始化時的值。

我建議在兩種情況下都使用None作爲默認關鍵字參數,因爲poke和其他人建議。您的代碼可能類似於:

def gamesplayed(self, team=None, startyear=None, endyear=None): 
    if not startyear: 
     startyear = self._firstseason 
    if not endyear: 
     endyear = self._lastseason 
+0

我一定會在我的代碼中使用這種方法。 –

+1

如果有人使用0和9999來調用覆蓋所有年份的函數,則更好地使用「如果年份爲無」。 –