How define constructor implementation for an Abstract Class in Python?

前端 未结 5 1144
难免孤独
难免孤独 2020-12-29 01:32

I am trying to declare an abstract class A with a constructor with a default behavior: all subclasses must initialize a member self.n:



        
相关标签:
5条回答
  • 2020-12-29 01:59

    You should define the methods as abstract as well with the @abc.abstractmethod decorator.

    0 讨论(0)
  • 2020-12-29 02:00

    You can implement something like below :

    from abc import ABC
    class A(ABC):
        def __init__(self, n):
            self.n = n
            super(A,self).__init__()
    

    Instantiating this class would throw an error

    0 讨论(0)
  • 2020-12-29 02:01

    Making the __init__ an abstract method:

    from abc import ABCMeta, abstractmethod
    
    class A(object):
        __metaclass__ = ABCMeta
    
        @abstractmethod
        def __init__(self, n):
            self.n = n
    
    
    if __name__ == '__main__':
        a = A(3)
    

    helps:

    TypeError: Can't instantiate abstract class A with abstract methods __init__
    

    Python 3 version:

    from abc import ABCMeta, abstractmethod
    
    class A(object, metaclass=ABCMeta):
    
        @abstractmethod
        def __init__(self, n):
            self.n = n
    
    
    if __name__ == '__main__':
        a = A(3)
    

    Works as well:

    TypeError: Can't instantiate abstract class A with abstract methods __init__
    
    0 讨论(0)
  • 2020-12-29 02:03

    A not so elegant solution can be this:

    class A(object):
      def __init__(self, n):
        if self.__class__ == A:
          raise Exception('I am abstract!')
        self.n = n
    

    Usage

    class B(A):
      pass
    a = A(1)  # Will throw exception
    b = B(1)  # Works fine as expected.
    
    0 讨论(0)
  • 2020-12-29 02:14

    You can override __new__ method to prevent direct instantiation.

    class A(object):
        __metaclass__ = ABCMeta
    
        def __new__(cls, *args, **kwargs):
            if cls is A:
                raise TypeError(
                    "TypeError: Can't instantiate abstract class {name} directly".format(name=cls.__name__)
                )
            return object.__new__(cls)
    

    Output:

    >>> A()
    Traceback (most recent call last):
      File "<ipython-input-8-3cd318a12eea>", line 1, in <module>
        A()
      File "/Users/ashwini/py/so.py", line 11, in __new__
        "TypeError: Can't instantiate abstract class {name} directly".format(name=cls.__name__)
    TypeError: TypeError: Can't instantiate abstract class A directly
    
    0 讨论(0)
提交回复
热议问题