简体   繁体   中英

Python: how to subclass a class with a classmethod

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

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM