1

What is the pythonic way to have an intermediate class that overwrites some of the method’s from an Abstract parent, but not all. Must it also overwrite methods it does not wish to change?

class Animal(six.with_metaclass(ABCMeta, object)):):

    @abstractmethod
    def move(self):
        raise NotImplementedError()

    @abstractmethod
    def give_birth(self):
        raise NotImplementedError()

class Mammal(Animal):


   def move(self): # I want to inherit this method from Animal
        raise NotImplementedError()

    def give_birth(self):  # want to overwrite
        # not with eggs!



class Dog(Mammal):
    def move(self):
       return 'MOVED like a dog'

This code doesn’t actually break, but my IDE (pycharm) highlights “class Mammal” and says “must implement all abstract methods". Maybe Animal.move shouldn't be abstract?

Sam Shleifer
  • 1,716
  • 2
  • 18
  • 29
  • You want to inherit `move` from `Animal` but it's an abstract method so it doesn't have an implementation in `Animal`. You'll have to make a concrete implementation of `Animal.move` (i.e. not an `abstractmethod`) if you want to inherit it as you say. What exactly is confusing you? – FHTMitchell Aug 06 '18 at 14:43
  • unfortunate that I am forced to replace Animal.get_move with identical code. Thought there might be a better way. – Sam Shleifer Aug 06 '18 at 14:46
  • I don't understand, what is `Animal.get_move`? What identical code, I don't see any code repitition? Why is this solution not satisfactory? Can you be a bit more clear? – FHTMitchell Aug 06 '18 at 14:48
  • I think I would ignore the IDE warning. Mammal is essentially an abstract class as well. – miah Aug 06 '18 at 14:51
  • Sorry. I edited the question to reflect that I only want to implement Dog.move, not Mammal.move. I think solution is to remove the decorator above Animal.move's definition – Sam Shleifer Aug 06 '18 at 14:51
  • Oh I see. Thanks for the edit. I think any option is fine. Repeat the code (makes it obvious to the reader what you are doing) or make it clear that `Mammal` is an abstract class to by setting it's metaclass to `ABCMeta` (or subclass `ABC`) – FHTMitchell Aug 06 '18 at 14:54

1 Answers1

4

You can make Mammal an abstract class as well, and it will not be required to implement the methods

from abc import ABC

class Animal(ABC):  # I've never used six, but your way of doing things should work here too
    @abstractmethod
    def move(self):
        raise NotImplementedError()    
    @abstractmethod
    def give_birth(self):
        raise NotImplementedError()

class Mammal(Animal, ABC):
    def give_birth(self):  # want to overwrite
        print("Live birth")

class Dog(Mammal):
    def move(self):
        print("Run in circles")
Patrick Haugh
  • 59,226
  • 13
  • 88
  • 96