Reputation: 6117
Is there a way to mark a python class as abstract or un-instantiable even if all its abstract methods have been implemented?
class Component(ABC):
@abstractmethod
def operation(self) -> None:
pass
class Decorator(Component): # I would like this class to be abstract
def operation(self) -> None:
print("basic operation")
The only workaround I found is to choose some method in the class to have both implementation and @abstractmethod
decorator, but then python requires derivers of the child abstract class to re-implement the method.
This too can be worked around by having the child class calling super()
, but pylint
complains that this is a useless call.
class Component(ABC):
@abstractmethod
def operation(self) -> None:
pass
class Decorator(Component): # I would like this class to be abstract
@abstractmethod
def operation(self) -> None:
print("basic operation")
class ConcreteDecorator(Decorator):
def operation(self) -> None: # python makes child class re-implement
super().operation() # pylint complains about useless super delegation
Is there a better way to do this?
I tried using a method with implementation and @abstractmethod
decorator, but then deriving classes need to reimplement.
I'm looking for a solution at "compile time", not a run time error.
Upvotes: 6
Views: 510
Reputation: 43103
Create a helper class that overrides the __new__
function to check whether cls.__bases__
contains itself.
class UnInstantiable:
def __new__(cls, *args, **kwargs):
if __class__ in cls.__bases__:
raise TypeError(f"Can't instantiate un-instantiable class {cls.__name__}")
return super().__new__(cls)
Usage:
# class Decorator(Component): # Add UnInstantiable base class
class Decorator(Component, UnInstantiable): # like this
def operation(self) -> None:
print("basic operation")
Decorator() # TypeError: Can't instantiate un-instantiable class Decorator
Upvotes: 1