2012-01-03 23 views
3

我試圖寫一個類中的一個遞歸函數的遞歸方法的說法,但使用對象的VAR作爲方法的參數有一些麻煩:使用對象變量作爲一個Python類

class nonsense(object): 
    def __init__(self, val): 
    self.val = val 
    def factorial(self, n=self.val): 
    if n<=1: return 1 
    return n*self.factorial(n=n-1) 

上面的代碼生成以下錯誤:

Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 4, in nonsense 
NameError: name 'self' is not defined 

但是,如果我不指self.val,誤差就會消失,但不必指定n是多餘的:

class nonsense(object): 
    def __init__(self, val): 
    self.val = val 
    def factorial(self, n): 
    if n<=1: return 1 
    return n*self.factorial(n=n-1) 

這樣做的正確方法是什麼?

回答

3

當你發現,你不能在頭self.xxx - 而有None,然後正確的身體:

def factorial(self, n=None): 
    if n is None: n = self.val 
    if n<=1: return 1 
    return n*self.factorial(n=n-1) 

的原因是,正在創建的類對象時,有沒有self ;除了globals(),當Python獲得factorial時定義的唯一名稱是__module____init__

作爲一個實驗來證明這一點,試試這個:

class TestClassCreation(object): 
    print("Started creating class") 
    print("names so far: %s" % vars()) 

    def __init__(self): 
     pass 
    print("now we have %s" % vars()) 

    def noop(self, default=None): 
     print("this gets run when noop is called") 
    print("and now have %s" % vars()) 
    print() 

    print("and now we'll fail...") 
    def failure(self, some_arg=self.noop): 
     pass 
    print("we never get here...") 
6

默認參數在方法定義時進行評估。因此,使用__init__中定義的成員值實質上「已經太晚了」。你應該做的是在函數體中的默認值設置爲None和測試這樣的:

class nonsense(object): 
    def __init__(self, val): 
     self.val = val 
    def factorial(self, n=None): 
     if n is None: 
      n = self.val 
     elif n <= 1: 
      return 1 

     return n*self.factorial(n-1) 
+0

簡明和清晰。謝謝。 – qed 2012-01-03 02:57:31

1

的原因奇怪的行爲是def語句只被執行一次,被定義函數時。因此,初始值只能創建一次,而當時還沒有self引用。

作爲替代,嘗試:

class nonsense(object): 
    def __init__(self, val): 
    self.val = val 
    def factorial(self, n=None): 
    return self.factorial_aux(n if n is not None else self.val) 
    def factorial_aux(self, n): 
    if n <= 1: 
     return 1 
    return n * self.factorial(n-1) 

上述溶液僅當n參數具有默認值(None)和在這之後,它返回調用factorial_aux的結果測試一次(它執行實際工作)與適當的論點。

0

爲什麼不寫是簡單地作爲呢?

class fact1(): 
    def fact2(self, num): 
     if num==1: 
      return 1 
     ss=num*self.fact2(num-1) 
     return ss 

exx=fact1() 
print exx.fact2(5) 

輸出120

+0

因爲這不簡單明瞭。比較'fact(5)'和'fact1()。fact2(5)'。 – 2012-01-09 17:53:37