1

If I create an abstract class in python using abc with an abstractmethod as follows and create a concrete class which doesn't use def to override the abstractmethod but instead attempt to set the attribute in the init function, it continues to throw the error that we can't instantiate an abstract class. I found out that I can get around this problem by creating a dummy of the abstractmethod. Is this the recommended way?

from abc import ABC, abstractmethod

class MyAbstract(ABC):
  def __init__(self):
    pass

  @abstractmethod
  def hi(self):
    pass

class Concrete(MyAbstract):
  def __init__(self, selector):
     if selector:
       self.hi = self.hi_a
     else:
       self.hi = self.hi_b

  def hi(self):
    '''
    Is it possible to not have to create this function?
    '''
    pass

  def hi_a(self):
     print('a')

  def hi_b(self):
     print('b')
1
  • 1
    You cannot instantiate class with abstract methods, and in order to call __init__, you need an instance. I'd suggest moving the selector logic to hi itself. Commented Sep 12, 2024 at 6:52

3 Answers 3

1
class Concrete(MyAbstract):
    hi = None

    ...

This suffices to allow instantiation. The class simply mustn't have any attribute decorated with @abstractXXX at time of instantiation. Replacing the inherited hi with any other hi is enough to achieve that.

Sign up to request clarification or add additional context in comments.

Comments

1

From documentation:

A class that has a metaclass derived from ABCMeta cannot be instantiated unless all of its abstract methods and properties are overridden.

and

Dynamically adding abstract methods to a class, or attempting to modify the abstraction status of a method or class once it is created, are only supported using the update_abstractmethods() function.

Comments

1

found out that I can get around this problem by creating a dummy of the abstractmethod. Is this the recommended way?

Yes, a dummy method or attribute is necessary to tell ABC that the abstract method has been supplied.

Normally, if a method is dynamically added to a class, you can trigger an update to __abstractmethods__ by calling update_abstractmethods(cls). However, your code adds a bound method to the instance. This won't be detected by the ABC logic. So, nothing short of putting a dummy in the class will suffice since the dynamic update is only done to the instance.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.