K Engle
K Engle

Reputation: 1562

Why does my __init__ function need to be @classmethod?

Here is a code snippet I wrote as a test. I noticed that if I don't define the init method as a classmethod, the code doesn't run:

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

This outputs:

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'

However if I change my init function to be @classmethod, the code works as intended:

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

Output:

1
2

I was under the impression init was by default a class method whose first argument must be self. What is going on?

Upvotes: 1

Views: 1145

Answers (1)

Ethan Furman
Ethan Furman

Reputation: 69240

The problem is that you have add marked as a classmethod, but it isn't. Take out the @classmethod from the adds and it should work.

Upvotes: 5

Related Questions