Search code examples
python-3.xabstract-class

Why add a abstract method to __init__ method of abstract class as an attribute?


I am reading a book about python design patterns. I feel a little puzzled When I see the code about 'factory' pattern.

class Profile(metaclass=ABCMeta):
    def __init__(self):
        self.sections = []
        **self.create_profile()**

    @abstractmethod
    def **create_profile**(self):
        pass

    def get_section(self):
        return self.sections

The method create_profile is a abstract method and it was add into init method. Please let me clear the reason that why do that.

Thanks a lot


Solution

    • It means when you write a subclass to inherit Profile, you must override the abstract method.

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

    example code:

    from abc import ABCMeta, abstractmethod
    class Profile(metaclass=ABCMeta):
        def __init__(self):
            self.sections = []
            self.create_profile()
    
        @abstractmethod
        def create_profile(self):
            pass
    
        def get_section(self):
            return self.sections
        
    class SubProfile(Profile):
        def __init__(self):
           self.create_profile()
    
        def create_profile(self):
            self.sections = [1,2,3]
    
    class AnotherSubProfile(Profile):
        def __init__(self):
           self.create_profile()
    
        def create_profile(self):
            self.sections = [4,5,6]
    
    class NoCreateSubProfile(Profile):
        def __init__(self):
           self.sections = [7,8,9]
        
    sub = SubProfile()
    print(sub.get_section())
    sub = AnotherSubProfile()
    print(sub.get_section())
    sub = NoCreateSubProfile()
    print(sub.get_section())
    

    result:

    [1, 2, 3]
    [4, 5, 6]
    TypeError: Can't instantiate abstract class NoCreateSubProfile with abstract method create_profile
    

    Edit: about why it was add into init method, I think it is just a simple example, so the book writer put the abstract method into init method so that you can call it when you create a object of the subclass to Profile without any extra actions that need to do.

    • In other fancy words, create_profile in init may indicate Profile must be created first when the instance of Profile are created.
    • create_profile not in init example:(basic the same to former one)
    from abc import ABCMeta, abstractmethod
    class Profile(metaclass=ABCMeta):
        def __init__(self):
            self.sections = []
            # self.create_profile()
    
        @abstractmethod
        def create_profile(self):
            pass
    
        def get_section(self):
            return self.sections
        
    class SubProfile(Profile):
        def __init__(self):
            pass
    
        def create_profile(self):
            self.sections = [1,2,3]
        
    sub = SubProfile()
    sub.create_profile()
    print(sub.get_section())