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
Answer from Wtower on Stack Overflow
Top answer
1 of 13
183

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
2 of 13
127

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, abstractmethod


class Base(ABC):

    @classmethod
    @property
    @abstractmethod
    def CONSTANT(cls):
        raise NotImplementedError

    def print_constant(self):
        print(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.

🌐
Python
docs.python.org › 3 › library › abc.html
abc — Abstract Base Classes
In order to correctly interoperate with the abstract base class machinery, the descriptor must identify itself as abstract using __isabstractmethod__. In general, this attribute should be True if any of the methods used to compose the descriptor ...
🌐
Python.org
discuss.python.org › ideas
Provide a canonical way to declare an abstract class variable - Ideas - Discussions on Python.org
October 28, 2024 - There’s a recent help post of Abstract variables in abc that asks about how an “abstract variable” can be declared such that it is required for a subclass to override the variable, to which @drmason13 replied: Although…
🌐
Python.org
discuss.python.org › ideas
[abc] Add abstract attributes via `abstract` type-hint - Ideas - Discussions on Python.org
April 24, 2023 - Feature or enhancement Add a special generic type hint abstract, that allows specifying that subclasses must implement an attribute. from abc import ABC, abstract class Foo(ABC): myattr: abstract[int] # <- subcla…
🌐
GeeksforGeeks
geeksforgeeks.org › python › abstract-classes-in-python
Abstract Classes in Python - GeeksforGeeks
Abstract properties enforce that a subclass provides the property’s implementation. They are especially useful when you want all subclasses to have a certain attribute (like species, category or type).
Published   September 3, 2025
🌐
GitHub
github.com › python › mypy › issues › 4426
Should we always prohibit "abstract" attributes? · Issue #4426 · python/mypy
November 20, 2017 - Currently, instantiating explicit subclasses of protocols with "abstract" attributes is prohibited: class P(Protocol): x: int # Note, no r.h.s. class C(P): pass class D(P): def __init__(self) -> None: self.x = 42 C() # E: Cannot instanti...
Author   ilevkivskyi
Find elsewhere
🌐
DataCamp
datacamp.com › tutorial › python-abstract-classes
Python Abstract Classes: A Comprehensive Guide with Examples | DataCamp
January 22, 2025 - By guaranteeing that every feature specified in the abstract class is completely implemented in its concrete subclasses, this enforcement improves the codebase's integrity. With this foundation, let's dive deeper into how Python supports abstract properties using the @property and @abstractmethod decorators, enabling developers to enforce attribute consistency alongside methods.
Top answer
1 of 8
78

A possibly a bit better solution compared to the accepted answer:

from better_abc import ABCMeta, abstract_attribute    # see below

class AbstractFoo(metaclass=ABCMeta):

    @abstract_attribute
    def bar(self):
        pass

class Foo(AbstractFoo):
    def __init__(self):
        self.bar = 3

class BadFoo(AbstractFoo):
    def __init__(self):
        pass

It will behave like this:

Foo()     # ok
BadFoo()  # will raise: NotImplementedError: Can't instantiate abstract class BadFoo
# with abstract attributes: bar

This answer uses same approach as the accepted answer, but integrates well with built-in ABC and does not require boilerplate of check_bar() helpers.

Here is the better_abc.py content:

from abc import ABCMeta as NativeABCMeta

class DummyAttribute:
    pass

def abstract_attribute(obj=None):
    if obj is None:
        obj = DummyAttribute()
    obj.__is_abstract_attribute__ = True
    return obj


class ABCMeta(NativeABCMeta):

    def __call__(cls, *args, **kwargs):
        instance = NativeABCMeta.__call__(cls, *args, **kwargs)
        abstract_attributes = {
            name
            for name in dir(instance)
            if hasattr(getattr(instance, name), '__is_abstract_attribute__')
        }
        if abstract_attributes:
            raise NotImplementedError(
                "Can't instantiate abstract class {} with"
                " abstract attributes: {}".format(
                    cls.__name__,
                    ', '.join(abstract_attributes)
                )
            )
        return instance

The nice thing is that you can do:

class AbstractFoo(metaclass=ABCMeta):
    bar = abstract_attribute()

and it will work same as above.

Also one can use:

class ABC(ABCMeta):
    pass

to define custom ABC helper. PS. I consider this code to be CC0.

This could be improved by using AST parser to raise earlier (on class declaration) by scanning the __init__ code, but it seems to be an overkill for now (unless someone is willing to implement).

2021: typing support

You can use:

from typing import cast, Any, Callable, TypeVar


R = TypeVar('R')


def abstract_attribute(obj: Callable[[Any], R] = None) -> R:
    _obj = cast(Any, obj)
    if obj is None:
        _obj = DummyAttribute()
    _obj.__is_abstract_attribute__ = True
    return cast(R, _obj)

which will let mypy highlight some typing issues

class AbstractFooTyped(metaclass=ABCMeta):

    @abstract_attribute
    def bar(self) -> int:
        pass


class FooTyped(AbstractFooTyped):
    def __init__(self):
        # skipping assignment (which is required!) to demonstrate
        # that it works independent of when the assignment is made
        pass


f_typed = FooTyped()
_ = f_typed.bar + 'test'   # Mypy: Unsupported operand types for + ("int" and "str")


FooTyped.bar = 'test'    # Mypy: Incompatible types in assignment (expression has type "str", variable has type "int")
FooTyped.bar + 'test'    # Mypy: Unsupported operand types for + ("int" and "str")

and for the shorthand notation, as suggested by @SMiller in the comments:

class AbstractFooTypedShorthand(metaclass=ABCMeta):
    bar: int = abstract_attribute()


AbstractFooTypedShorthand.bar += 'test'   # Mypy: Unsupported operand types for + ("int" and "str")
2 of 8
41

Just because you define it as an abstractproperty on the abstract base class doesn't mean you have to make a property on the subclass.

e.g. you can:

In [1]: from abc import ABCMeta, abstractproperty

In [2]: class X(metaclass=ABCMeta):
   ...:     @abstractproperty
   ...:     def required(self):
   ...:         raise NotImplementedError
   ...:

In [3]: class Y(X):
   ...:     required = True
   ...:

In [4]: Y()
Out[4]: <__main__.Y at 0x10ae0d390>

If you want to initialise the value in __init__ you can do this:

In [5]: class Z(X):
   ...:     required = None
   ...:     def __init__(self, value):
   ...:         self.required = value
   ...:

In [6]: Z(value=3)
Out[6]: <__main__.Z at 0x10ae15a20>

Since Python 3.3 abstractproperty is deprecated. So Python 3 users should use the following instead:

from abc import ABCMeta, abstractmethod

class X(metaclass=ABCMeta):
    @property
    @abstractmethod
    def required(self):
        raise NotImplementedError
🌐
Real Python
realpython.com › ref › glossary › abstract-base-class
abstract base class (ABC) | Python Glossary – Real Python
This is useful for ensuring that ... program. To define an abstract base class, you inherit from abc.ABC and use the @abstractmethod decorator to mark methods that must be implemented by subclasses....
🌐
Earthly
earthly.dev › blog › abstract-base-classes-python
Abstract Base Classes in Python - Earthly Blog
July 19, 2023 - The get_name method returns the name attribute of the Bird object, while the make_sound method returns the string “Chirp chirp!”. These methods ensure that any object created from the Bird class has the required behavior defined in the Animal abstract class.
🌐
Scaler
scaler.com › home › topics › abstract class in python
Abstract Class in Python - Scaler Topics
April 9, 2024 - Here, we have first called the draw() method of the Shape class through super().draw() and then provided the additional implementation required. Let’s try to call the draw() method of Circle class again: ... In this way, we can provide a common high-level implementation for all the subclasses of the abstract base class, and those subclasses can provide their own implementation. Use this Compiler to compile your Python code.
🌐
Python Course
python-course.eu › oop › the-abc-of-abstract-base-classes.php
20. The 'ABC' of Abstract Base Classes | OOP | python-course.eu
We will define now a subclass using the previously defined abstract class. You will notice that we haven't implemented the do_something method, even though we are required to implement it, because this method is decorated as an abstract method with the decorator "abstractmethod".
Top answer
1 of 3
10

Previously, one the "solutions" to this type of problem was to stack @property, @classmethod, and @abstractmethod together to produce an "abstract class property`.

According to CPython issue #89519, chaining descriptor decorators like @classmethod or @staticmethod with @property can behave really poorly, so it has been decided that chaining decorators like this is deprecated beginning Python 3.11, and will now error with tools like mypy.

There is an alternative solution if you really need something that behaves like an abstract class property, as explained in this comment, especially if you need a property for some expensive/delayed accessing. The trick is to supplement using @abstractmethod with subclassing typing.Protocol.

from typing import ClassVar, Protocol


class FooBase(Protocol):
    foo: ClassVar[str]


class Foo(FooBase):
    foo = "hello"


class Bar(FooBase):
    pass


Foo()
Bar()  # Cannot instantiate abstract class "Bar" with abstract attribute "foo"

Note that although linters can catch this type of error, it is not enforced at runtime, unlike creating a subclass of abc.ABC which causes a runtime error if you try to instantiate a class with an abstract property.

Additionally, the above approach does not support the use of foo = Descriptor(), similar to implementing an attribute with a @property instead. To cover both cases, you'll need to use the following:

from typing import Any, ClassVar, Optional, Protocol, Type, TypeVar, Union

T_co = TypeVar("T_co", covariant=True)


class Attribute(Protocol[T]):

    def __get__(self, instance, owner=None) -> T_co:
        ...


class FooBase(Protocol):
    foo: ClassVar[Union[Attribute[str], str]]


class Foo(FooBase):
    foo = "hello"


class Foo:

    def __get__(self, instance: Any, owner: Optional[Type] = None) -> str:
        return "hello"


class Bar(FooBase):
    foo = Foo()


Foo()
Bar()

Both classes pass type checks and actually work at runtime as intended, although again nothing is enforced at runtime.

2 of 3
2

This is a partial answer. You can use

class FooBase(ABC):
    @property
    @classmethod
    @abstractmethod
    def foo(cls) -> str:
        ...

class Foo(FooBase):
    foo = "hi"

def go(f: FooBase) -> str:
    return f.foo

It's only partial because you'll only get a mypy error if you try to instantiate Foo without an initialized foo, like

class Foo(FooBase):
    ...

Foo()  # error: Cannot instantiate abstract class "Foo" with abstract attribute "foo"

This is the same behaviour as when you have a simple @abstractmethod. Only when instantiating it is the error raised. This is expected because Foo might not be intended as a concrete class, and may itself be subclassed. You can mitigate this somewhat by stating it is a concrete class with typing.final. The following will raise an error on the class itself.

@final
class Foo(FooBase):  # error: Final class __main__.Foo has abstract attributes "foo"
   ...
🌐
The Teclado Blog
blog.teclado.com › python-abc-abstract-base-classes
How to Write Cleaner Python Code Using Abstract Classes
October 26, 2022 - We use @abstractmethod to define a method in the abstract base class and combination of @property and @abstractmethod in order to define an abstract property. I hope you learnt something new today! If you're looking to upgrade your Python skills even further, check out our Complete Python Course.
🌐
Python Module of the Week
pymotw.com › 2 › abc
abc – Abstract Base Classes - Python Module of the Week
$ python abc_concrete_method.py base class reading data subclass sorting data ['line one', 'line three', 'line two'] If your API specification includes attributes in addition to methods, you can require the attributes in concrete classes by defining them with @abstractproperty.
🌐
CodeFatherTech
codefather.tech › home › blog › create an abstract class in python: a step-by-step guide
Create an Abstract Class in Python: A Step-By-Step Guide
December 8, 2024 - Let’s add an attribute called speed to our abstract base class Aircraft and also property methods to read and modify its value. A way in Python to define property methods to read and modify the value of speed would be the following:
🌐
Upgrad
upgrad.com › home › tutorials › software & tech › abstract class in python
Abstract Class in Python | With Example and Interface Comparison
September 12, 2024 - Dog inherits from Animal and implements the sound() method, providing the required functionality for the abstract method. ... Unlike Animal, we can instantiate Dog because it has provided implementations for all abstract methods. In this case, the sound() method returns "Bark" when called. ... Abstract classes are meant to serve as blueprints for other classes. By preventing direct instantiation, Python ensures that an abstract class cannot be used before a subclass fully implements it.