2014-10-16 89 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

相关问题