为什么我的 __init__ 函数需要@classmethod?

K E*_*gle 1 python inheritance

这是我作为测试编写的代码片段。我注意到,如果我不将 init 方法定义为类方法,则代码不会运行:

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
Run Code Online (Sandbox Code Playgroud)

这输出:

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'
Run Code Online (Sandbox Code Playgroud)

但是,如果我将 init 函数更改为@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
Run Code Online (Sandbox Code Playgroud)

输出:

1
2
Run Code Online (Sandbox Code Playgroud)

我的印象是 init 默认是一个类方法,其第一个参数必须是 self。到底是怎么回事?

Eth*_*man 5

问题是您已add标记为 a classmethod,但事实并非如此。@classmethod从s中取出add,它应该可以工作。

  • 为了扩展这一点,当“add”被标记为“classmethod”时,调用“self.add(1)”不会传递“self”,而是传递“self.__class__”作为“add”的第一个参数。它更新(或尝试更新)“A.value”的值,而不是“a.value”或“b.value”。 (3认同)
  • 为了进一步扩展,使 __init__ 成为类方法似乎会有所帮助,因为在这种情况下,在 __init__ 中设置 self.value 实际上是设置 A.value 而不是 a.value,从而可以通过 add 访问它` 类方法。 (2认同)