Abstract attributes in Python [duplicate] Abstract attributes in Python [duplicate] python python

Abstract attributes in Python [duplicate]


Python 3.3+

from abc import ABCMeta, abstractmethodclass A(metaclass=ABCMeta):    def __init__(self):        # ...        pass    @property    @abstractmethod    def a(self):        pass    @abstractmethod    def b(self):        passclass B(A):    a = 1    def b(self):        pass

Failure to declare a or b in the derived class B will raise a TypeError such as:

TypeError: Can't instantiate abstract class B with abstract methods a

Python 2.7

There is an @abstractproperty decorator for this:

from abc import ABCMeta, abstractmethod, abstractpropertyclass A:    __metaclass__ = ABCMeta    def __init__(self):        # ...        pass    @abstractproperty    def a(self):        pass    @abstractmethod    def b(self):        passclass B(A):    a = 1    def b(self):        pass


Python has a built-in exception for this, though you won't encounter the exception until runtime.

class Base(object):    @property    def path(self):        raise NotImplementedErrorclass SubClass(Base):    path = 'blah'


Since this question was originally asked, python has changed how abstract classes are implemented. I have used a slightly different approach using the abc.ABC formalism in python 3.6. Here I define the constant as a property which must be defined in each subclass.

from abc import ABC, abstractmethodclass Base(ABC):    @property    @classmethod    @abstractmethod    def CONSTANT(cls):        return NotImplementedError    def print_constant(self):        print(type(self).CONSTANT)class Derived(Base):    CONSTANT = 42

This forces the derived class to define the constant, or else a TypeError exception will be raised when you try to instantiate the subclass. When you want to use the constant for any functionality implemented in the abstract class, you must access the subclass constant by type(self).CONSTANT instead of just CONSTANT, since the value is undefined in the base class.

There are other ways to implement this, but I like this syntax as it seems to me the most plain and obvious for the reader.

The previous answers all touched useful points, but I feel the accepted answer does not directly answer the question because

  • The question asks for implementation in an abstract class, but the accepted answer does not follow the abstract formalism.
  • The question asks that implementation is enforced. I would argue that enforcement is stricter in this answer because it causes a runtime error when the subclass is instantiated if CONSTANT is not defined. The accepted answer allows the object to be instantiated and only throws an error when CONSTANT is accessed, making the enforcement less strict.

This is not to fault the original answers. Major changes to the abstract class syntax have occurred since they were posted, which in this case allow a neater and more functional implementation.