I defined the abstract method sound() with @abstractmethod under the non-abstract class Animal which doesn't extend ABC and Cat class extends Animal class, then I could instantiate both Animal and Cat classes without any errors as shown below:
from abc import ABC, abstractmethod
class Animal: # Doesn't extend "ABC"
@abstractmethod # Here
def sound(self):
print("Wow!!")
class Cat(Animal):
pass
obj1 = Animal() # Here
obj1.sound()
obj2 = Cat() # Here
obj2.sound()
Output:
Wow!!
Wow!!
So, is an abstract method a normal instance method in a non-abstract class in Python?
The
abstractmethoddecorator just adds some annotation to the method, which is evaluated byABCwhen you try to instantiate the class. The method itself doesn't change in any way, it's still a regular instance method. It's the cooperation ofABCtogether with thoseabstractmethoddecorator annotations that result in the desired behaviour of preventing instantiation of "abstract classes". It's not a concept enforced at the language level in any way, it's just layered on top of regular Python classes.