Найти в Дзене
Властелин машин

Как создавать абстрактные классы в Python и когда они пригодятся

Не каждый способен всю жизнь дышать и питаться абстракциями. Абстракции восхитительны, но дышать воздухом и есть хлеб тоже, по-моему, надо (Герман Гессе). Абстрактные классы гарантируют, что их подклассы должны реализовать определенные методы. Это может быть полезно, когда вы разрабатываете общий функционал программы и предполагаете, что некоторые методы будут реализованы в конкретных подклассах. Например, если вы пишете скрипт скачивания объявлений с сайта продаж, на верхнем уровне можно реализовать функционал обхода страниц объявлений, а подкласс в зависимости от сайта будет уточнять методы парсинга полей определенного товара. Как и говорил выше, в основном классе мы можем создать скелет обхода страниц, а детали отдаются на откуп конкретной реализации (для гарантии этого выбрасываем исключение), так как для разных сайтов они будут меняться (например, для Авито, Юлы, Циан). Реализуем игрушечный шаблон подкласса, чтобы метод get_new_url возвращал 1 при атрибуте класса менее трех, а пот

Не каждый способен всю жизнь дышать и питаться абстракциями. Абстракции восхитительны, но дышать воздухом и есть хлеб тоже, по-моему, надо (Герман Гессе).

Абстрактные классы гарантируют, что их подклассы должны реализовать определенные методы. Это может быть полезно, когда вы разрабатываете общий функционал программы и предполагаете, что некоторые методы будут реализованы в конкретных подклассах.

Например, если вы пишете скрипт скачивания объявлений с сайта продаж, на верхнем уровне можно реализовать функционал обхода страниц объявлений, а подкласс в зависимости от сайта будет уточнять методы парсинга полей определенного товара.

Как и говорил выше, в основном классе мы можем создать скелет обхода страниц, а детали отдаются на откуп конкретной реализации (для гарантии этого выбрасываем исключение), так как для разных сайтов они будут меняться (например, для Авито, Юлы, Циан). Реализуем игрушечный шаблон подкласса, чтобы метод get_new_url возвращал 1 при атрибуте класса менее трех, а потом останавливал наш цикл обхода в walk (посылая в качестве очередного url 0):

-2

В связи с тем, что в методе walk организован обход страниц и их парсинг, должен быть реализован метод parse_items_in_url, иначе происходит вызов исключения. Поэтому если доопределить его, ошибка исчезает:

-3

-4

Указанная методика создания макета для базового класса является рабочей, однако уступает более современному способу, который извещает о необходимости реализации методов не на этапе исполнения, а создания экземпляра подкласса.

Для этого базовый шаблон следует сделать подклассом ABCMeta модуля abc, а требуемые для реализации методы помечать как абстрактные декоратором @abstractmethod. Кроме того, экземпляр такого класса в отличие от примера выше (ScraperBase) создать нельзя, что оправданно, так как он не обладает всем необходимым функционалом:

-5

-6

Без объявления всех методов экземпляр не создается. А так ошибка исчезает:

-7

-8