Abstract attributes in Python

deamon picture deamon · Apr 29, 2010 · Viewed 63.8k times · Source

What is the shortest / most elegant way to implement the following Scala code with an abstract attribute in Python?

abstract class Controller {

    val path: String

}

A subclass of Controller is enforced to define "path" by the Scala compiler. A subclass would look like this:

class MyController extends Controller {

    override val path = "/home"

}

Answer

Wtower picture Wtower · Jan 27, 2017

Python 3.3+

from abc import ABCMeta, abstractmethod


class A(metaclass=ABCMeta):
    def __init__(self):
        # ...
        pass

    @property
    @abstractmethod
    def a(self):
        pass

    @abstractmethod
    def b(self):
        pass


class 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, abstractproperty


class A:
    __metaclass__ = ABCMeta

    def __init__(self):
        # ...
        pass

    @abstractproperty
    def a(self):
        pass

    @abstractmethod
    def b(self):
        pass


class B(A):
    a = 1

    def b(self):
        pass