2

How can you ensure a concrete class will correctly use @property decorator when overriding an @abstractmethod?

Consider the following abstract class:

class Vehicle(ABC):

    def __init__(self):
        print(self.gas * 2)

    @property
    @abstractmethod
    def gas(self):
        raise NotImplementedError()

Vehicle relies on self.gas being a property, not a method. When attempting to inherit this class, if gas method is not overridden Python will correctly throw a TypeError. However, it is possible to incorrectly implement the gas method without the @property decorator, which will stop this error, yet result in an erroneous behaviour:

class Car(Vehicle):
    def gas(self):
        return 100

c = Car()

results in:

    print(self.gas * 2)
TypeError: unsupported operand type(s) for *: 'method' and 'int'

As you can see, the error is barely suggesting what may be the real cause of the issue. Do you know how to either prevent it or make the error more indicative of the true cause?


Python's documentation for @abstractmethod (link) states:

When abstractmethod() is applied in combination with other method descriptors, it should be applied as the innermost decorator

Followed by an example:

    @property
    @abstractmethod
    def my_abstract_property(self):

So I'm assuming using @property and @abstractmethod is not unusual.

Voy
  • 5,286
  • 1
  • 49
  • 59
  • The problem is you are calling a method at compile time and it will be calculated at the same time with your calculation, which will create a confusion which will be done first. How about assigning your abstract method to a variable first then do the math calculation ```gasValue = self.gas```, or make your method to do the calculation and return value final value of ```self.gas * 2```. You might also create a static variable in your abstract class. – furkanayd Dec 13 '19 at 05:56

0 Answers0