Python Abstract Property

Ammar Ali Feb 12, 2024
  1. Python Abstract Property
  2. Example: Calling the mileage Method of the Bike Class
  3. Example: Multiple @abstractmethod on Different Classes
  4. Example: Using the Register() Method
  5. Conclusion
Python Abstract Property

This tutorial will discuss using the abc or abstract base classes module to create classes with abstract properties in Python.

Python Abstract Property

Abstraction in object-oriented programming is used to hide unnecessary information from users. The inner workings of a function will be hidden from the user, but the user can use the function to perform a task.

For example, we use computer software to perform different tasks, but we don’t know how the software performs the task. We only give inputs to the software and get outputs from it.

We can use abstraction in Python to reduce the complexity of a program by hiding irrelevant information.

A class will become abstract if it contains one or more abstract methods. Abstract methods are defined in a subclass, and the abstract class will be inherited from the subclass because abstract classes are blueprints of other classes.

In Python, we can use the abc module or abstract base classes module to implement abstract classes. The abstract base class provides an interface for subclasses, and it is beneficial when the code is large and remembering all the classes is challenging.

We need to import the abc module in the base class and use it to decorate the base class method as an abstract. To define an abstract method, we can use the @abstractmethod decorator before defining the method in the base class, and we can use the @property decorator to make a method an abstract property.

For example, let’s import the abc module and create a Bike class that will be inherited from the ABC class. Inside the Bike class, we will create an abstract method, mileage().

We can now inherit the base class to implement different subclasses with abstract methods. See the code below.

# Class Code
from abc import ABC, abstractmethod


class Bike(ABC):
    @property
    @abstractmethod
    def mileage(self):
        pass


class Honda(Bike):
    def mileage(self):
        print("The mileage is 20kmph")


class CD70(Bike):
    def mileage(self):
        print("The mileage is 15kmph ")


class CD150(Bike):
    def mileage(self):
        print("The mileage is 34kmph ")


# Main Code

h = Honda()
h.mileage()

r = CD70()
r.mileage()

s = CD150()
s.mileage()

The code above defines a set of classes related to different types of bikes, including an abstract base class Bike with an abstract property mileage. Three concrete classes, Honda, CD70, and CD150, inherit from Bike and provide their own implementations of the mileage property.

The Bike class is an abstract base class (ABC) that inherits from ABC (Abstract Base Class) and declares an abstract property mileage using the @property and @abstractmethod decorators.

The Honda, CD70, and CD150 classes inherit from the Bike abstract class.

The mileage method is called on each instance to print the specific mileage information for each type of bike.

Output:

The mileage is 20kmph
The mileage is 15kmph
The mileage is 34kmph

In the above code, we created objects of the subclasses, and then we called their method mileage(), which will print the mileage of the bike.

Example: Calling the mileage Method of the Bike Class

The Bike class also has the mileage() method, but we cannot call it because the method is abstract.

For example, let’s repeat the above example and call the mileage method of the Bike class. See the code below.

# Class Code
from abc import ABC, abstractmethod


class Bike(ABC):
    @property
    @abstractmethod
    def mileage(self):
        pass


class Honda(Bike):
    def mileage(self):
        print("The mileage is 20kmph")


class CD70(Bike):
    def mileage(self):
        print("The mileage is 15kmph ")


class CD150(Bike):
    def mileage(self):
        print("The mileage is 34kmph ")


# Main Code
b = Bike()
b.mileage()

The code defines an abstract base class (Bike) with an abstract property mileage. Three concrete subclasses (Honda, CD70, and CD150) inherit from Bike and provide specific implementations of the mileage property.

However, in the main code, an attempt is made to instantiate the abstract class Bike and call its mileage method, which results in an error (TypeError).

Output:

TypeError: Can't instantiate abstract class Bike with abstract methods mileage

The above code clearly says that the abstract class Bike has abstract methods, which is why its object cannot be created and its methods cannot be called.

Example: Multiple @abstractmethod on Different Classes

We can also make methods of other classes as abstract methods using the @abstractmethod decorator before the definition of the first method. When one tries to make an object of that class to access the methods, Python will give an error.

For example, let’s make the methods of a subclass abstract. See the code below.

# Class Code
from abc import ABC, abstractmethod


class Bike(ABC):
    @property
    @abstractmethod
    def mileage(self):
        pass


class Honda(Bike):
    @abstractmethod
    def mileage(self):
        print("The mileage is 20kmph")

    def mileage2(self):
        print("The mileage is 200 kmph")


# Main Code
b = Honda()
b.mileage2()

In the code snippet above, Honda is a concrete class that inherits from Bike.

It provides a specific implementation of the mileage property using the @abstractmethod decorator.

Additionally, it has a non-abstract method (mileage2) that prints a different mileage value. The error occurs because Honda is still considered an abstract class due to the presence of the abstract property mileage declared in the base class Bike.

Since the mileage property in Bike is abstract and does not have a concrete implementation in Honda, attempting to instantiate Honda directly results in a TypeError.

Output:

TypeError: Can't instantiate abstract class Honda with abstract methods mileage

We have defined two methods in the Honda class, but none of them is accessible because the class is abstract. Check this link for more details about the abstract base classes.

Example: Using the Register() Method

The register() method in Python’s abc module is a mechanism that allows a class to be recognized as a virtual subclass of an abstract base class (ABC) without explicitly inheriting from it.

This method is useful when you have an existing class that you want to designate as a subclass of an abstract class, even if it doesn’t inherit from it in the traditional sense.

See the code below.

from abc import ABC, abstractmethod


class Bike(ABC):
    @property
    @abstractmethod
    def mileage(self):
        pass


class Honda:
    @property
    def mileage(self):
        return "The mileage is 20kmph"


# Registering Honda as a virtual subclass of Bike
Bike.register(Honda)

# Instantiate Honda
b = Honda()

# Accessing the abstract property
print(b.mileage)

In this example, Honda is registered as a virtual subclass of Bike. The mileage property is then accessible on an instance of Honda, even though Honda does not explicitly inherit from Bike.

Also, the Honda class is now marked as a property using the @property decorator. When you access b.mileage, it correctly prints The mileage is 20kmph without raising an AttributeError.

Output:

The mileage is 20kmph

Now that we added the return statement in the mileage method of the Honda class, the property should correctly return the specified string and expect to see The mileage is 20kmph in the result.

Conclusion

This tutorial introduces Python abstract properties using the abc module.

Abstract properties and classes are used to achieve abstraction in object-oriented programming, hiding unnecessary details from users.

The tutorial covers the implementation of abstract properties, creating abstract base classes, and providing concrete implementations in subclasses. It emphasizes the use of the @abstractmethod decorator and the @property decorator to define abstract methods and properties.

The tutorial also explores scenarios where abstract classes cannot be instantiated directly and introduces the register() method for designating virtual subclasses.

Code examples illustrate the concepts, providing a comprehensive understanding of abstract properties in Python.

Author: Ammar Ali
Ammar Ali avatar Ammar Ali avatar

Hello! I am Ammar Ali, a programmer here to learn from experience, people, and docs, and create interesting and useful programming content. I mostly create content about Python, Matlab, and Microcontrollers like Arduino and PIC.

LinkedIn Facebook

Related Article - Python Class