Reputation: 121
I am trying to make a subclass from a class with a @classmethod defined:
class Pet(object):
def __init__(self,animal):
self.animal = animal
@classmethod
def wild(cls,animal):
return cls('wild '+animal)
class Cat(Pet):
def __init__(self):
Pet.wild('cat')
if __name__ == '__main__':
print Cat().animal
This gives me the following error:
print Cat().animal
AttributeError: Cat instance has no attribute 'animal'
Probably I don't fully understand the concept of subclassing, I have been also trying to pass self
to Pet.wild
without much more success. Any help would be really appreciated!
EDIT
I try to explain what I want to do: I would like to initialize parentclass (or superclass?) Pet
from the Cat
subclass using the classmethod wild
and not using __init__
. Is this possible? Thank you
Upvotes: 3
Views: 6241
Reputation: 76
So if you want to add inheritance and extend Cat later here is how you would do it. See this post for the difference between __new__
and __init__
class Pet(object):
def __init__(self, animal):
self.animal = animal
@classmethod
def wild(cls, animal):
obj = cls.__new__(cls)
obj.animal = "wind " + animal
return obj
class Cat(Pet):
pass
if __name__ == "__main__":
print Pet.wild("cat").animal
cat = Cat.wild("cat")
house_cat = Cat("cat")
print house_cat.animal, cat.animal
Here is what is going on under the covers. Cat inherits the wild
classmethod too. So you don't have to call Pet.wild
from within Cat
constructor. You just call the wild
classmethod directly on Cat
. cls
gets the Cat
class and so the object created will be Cat
instance and not a Pet
instance. However, at some point you will have to override some default behavior in constructor and that involves some amount of coding.
Upvotes: 2
Reputation: 26578
That is because you are not calling super to properly inherit from your base class. So, doing this:
Pet.wild('cat')
does not do what you expect.
class Pet(object):
def __init__(self,animal):
self.animal = animal
@classmethod
def wild(cls,animal):
return cls('wild '+animal)
class Cat(Pet):
def __init__(self):
super(Cat, self).__init__('cat')
if __name__ == '__main__':
print Cat().animal
Upvotes: 4