2014-10-16 90 views
0

這是我寫作測試的代碼片段。我注意到,如果我不定義init方法作爲類方法,代碼不運行:爲什麼我的__init__函數需要是@classmethod?

class A(object): 
    def __init__(self): 
     self.value = 0 
     self.add(1) 

    @classmethod 
    def add(self, arg): 
     self.value += arg 

class B(A): 
    @classmethod 
    def add(self, arg): 
     self.value += arg * 2 

if __name__ == '__main__': 
    a = A() 
    b = B() 
    print a.value 
    print b.value 

此輸出:

Traceback (most recent call last): 
    File "inherit.py", line 17, in <module> 
    a = A() 
    File "inherit.py", line 4, in __init__ 
    self.add(1) 
    File "inherit.py", line 8, in add 
    self.value += arg 
AttributeError: type object 'A' has no attribute 'value' 

但是,如果我改變我的初始化函數是@classmethod ,代碼按預期工作:

class A(object): 
    @classmethod 
    def __init__(self): 
     self.value = 0 
     self.add(1) 

    @classmethod 
    def add(self, arg): 
     self.value += arg 

class B(A): 
    @classmethod 
    def add(self, arg): 
     self.value += arg * 2 

if __name__ == '__main__': 
    a = A() 
    b = B() 
    print a.value 
    print b.value 

輸出:

1 
2 

我在印象之下init默認是一個類方法,它的第一個參數必須是self。到底是怎麼回事?

+4

我不認爲你明白什麼是classmethod。默認情況下'__init__'不是一個類方法,代碼中的任何方法都不應該是類方法。 – jwodder 2014-10-16 19:18:55

+0

它可能不像預期的那樣工作。嘗試以下操作:'a1 = A(); a2 = A(); a1.add(1);斷言a1.value == a2.value'。 – chepner 2014-10-16 19:40:06

回答

4

問題是你有add標記爲classmethod,但事實並非如此。從add中取出@classmethod,它應該可以工作。

+3

爲了擴展這個,當'add'被標記爲'classmethod'時,調用'self.add(1)'不會傳遞'self',而是'self .__ class__',作爲add的第一個參數。 。它更新(或嘗試更新)'A.value'的值,而不是'a.value'或'b.value'。 – chepner 2014-10-16 19:36:11

+2

爲了進一步擴展,使'__init__'成爲類方法似乎有所幫助,因爲在這種情況下,在__init__中設置self.value實際上是將'A.value'而不是'a.value'設置爲可以從'添加'classmethod。 – Wilduck 2014-10-16 19:45:28

相關問題