Понимание абстрактных базовых классов в Python

Я читал об абстрактном базовом классе и наткнулся на https://www.python-course.eu/python3_abstract_classes.php. Я получил общее представление о них, но нашел два противоречащих друг другу утверждения.

Подклассы абстрактного класса в Python не обязаны реализовывать абстрактные методы родительского класса.

и

Класс, производный от абстрактного класса, не может быть создан, пока не будут переопределены все его абстрактные методы.

Насколько я понимаю первое утверждение, производный класс не обязан реализовывать абстрактный метод родительского класса, что неверно. Я сделал пример программы, чтобы проверить это.

from abc import ABC, abstractmethod

class AbstractClassExample(ABC):

    @abstractmethod
    def do_something(self):
        print("Some implementation!")

class AnotherSubclass(AbstractClassExample):

    def just_another_method(self):
        super().do_something()
        print("The enrichment from AnotherSubclass")

x = AnotherSubclass() # TypeError: Can't instantiate abstract class AnotherSubclass with abstract methods do_something
x.do_something()

Я хотел бы объяснить, что означает первое утверждение (желательно с примерами).


person Pratik Gandhi    schedule 10.12.2019    source источник
comment
Ваш код демонстрирует первое утверждение, не так ли? Если вы удалите x = AnotherSubclass(), ваш код будет работать без ошибок.   -  person Sweeper    schedule 10.12.2019
comment
Если я удалю это, в программе ничего не будет работать, поэтому ошибки не будет. Я хочу сказать, что для создания экземпляра AnotherSubclass мы должны реализовать метод do_something, и я думаю, что первое утверждение противоречит этому.   -  person Pratik Gandhi    schedule 10.12.2019
comment
@Sweeper, о, кажется, теперь я понял, мы можем создать класс, но не создавать его экземпляр?   -  person Pratik Gandhi    schedule 10.12.2019
comment
Точно! Об этом говорится в первом утверждении. Обратите внимание, что это более тонко, чем программа ничего не делает, поэтому, конечно, никакой ошибки! потому что если вы, скажем, попытаетесь удалить несколько пустых мест в начале строк, вы получите ошибки, даже если ваша программа ничего не делает.   -  person Sweeper    schedule 10.12.2019
comment
Да, ваш второй комментарий понял. Я опубликую ответ.   -  person Sweeper    schedule 10.12.2019
comment
Так что это больше похоже на Subclasses of an abstract class in Python are not required to implement abstract methods of the parent class, but if you don't override then you won't be able to instantiate it.   -  person Pratik Gandhi    schedule 10.12.2019


Ответы (1)


Ваш код демонстрирует, что второе утверждение верно. Это не показывает, что первое утверждение ложно.

В своем коде вы пытаетесь создать экземпляр AnotherSubclass, что недопустимо, поскольку AnotherSubclass не реализует все абстрактные методы. Второе утверждение говорит об этом.

Однако, если вы удалите две последние строки, то есть не создадите экземпляр AnotherSubclass, тогда ваш код не будет выдавать ошибок при попытке его запуска. Это показывает, что первое утверждение верно — подклассы абстрактных классов, которые не реализуют все свои абстрактные методы, допускаются.

Вы можете написать еще один подкласс AnotherSubclass с именем YetAnotherClass, на этот раз реализовав абстрактный метод, и вы сможете создать экземпляр YetAnotherClass. Обратите внимание, что ваша программа теперь что-то делает, и AnotherSubclass все еще может существовать.

person Sweeper    schedule 10.12.2019