Интерфейсы Python: выбирайте протоколы вместо ABC
Несколько практических причин предпочесть новые блестящие протоколы
Я использовал стандартную библиотеку Python abcдля определения интерфейсов в течение последних 10 лет своей карьеры. Но недавно я обнаружил, что относительно новые протоколы Python намного лучше. Люди находят применение обеим технологиям. Но я хочу убедить вас полностью покинуть корабли и начать использовать их вместо более традиционных методов.
Интерфейсы Python: что можно использовать?
Python несколько отличается от других популярных языков, поскольку в нем нет интерфейсов на языковом уровне. Но есть несколько реализаций библиотек. Пакет abc, наверное, самый популярный:
from abc import ABC, abstractmethod
class Animal(ABC):
@abstractmethod
def eat(self, food) -> float:
pass
@abstractmethod
def sleep(self, hours) -> float:
pass
from zope.interface import Interface
class Animal(Interface):
def eat(self, food) -> float:
pass
def sleep(self, hours) -> float:
pass
Наконец, есть протоколы:
from typing import Protocol
class Animal(Protocol):
def eat(self, food) -> float:
...
def sleep(self, hours) -> float:
...
Что следует использовать?
Вы должны знать, что система интерфейса не будет локализована для небольшой части вашей кодовой базы. После того, как вы решите использовать один из них, вы будете видеть его повсюду, и в будущем его будет сложно изменить. Поэтому я бы сразу отклонил любые пользовательские реализации или файлы Zope. Это дополнительная зависимость, с которой вам придется иметь дело вечно: установка, версии, поддержка и так далее. Например, вам нужно установить плагин Mypy для поддержки zope.interfaceколодца. Кроме того, новый разработчик в команде может не знать этот специальный пакет, и вам придется объяснить, что это такое и почему вы его выбрали.
Основная битва произойдет между abcи Protocols. Но если вы действительно хотите битву zopeпротив Protocols, пожалуйста, прочитайте этот подробный анализ .
Статическая проверка в первую очередь
Большое предположение, которое я собираюсь сделать, заключается в том, что вы уже убеждены в том, что статическая проверка является обязательной : вы не собираетесь запускать код, который дает сбой pylint/mypy. Обе шашки поддерживают abcи Protocolsодинаково хорошо. Кроме того, просто знайте, что оба abcи Protocolsразрешите проверку во время выполнения, если вам это нужно.
Оба поддерживают явный синтаксис
Во-первых, обратите внимание, что вы по-прежнему можете явно наследовать от abc и от Protocol. Многие аргументы в очень хорошем видео (и комментариях) Арьяна вращаются вокруг неправильного представления о том, что вы не можете сделать это с помощью протоколов. Вы вполне можете:
class Giraffe(Animal):
...
class Giraffe: # no base class needed!
def eat(self, food) -> float:
return 0.
def sleep(self, hours) -> float:
return 1.
def feed_animal(animal: Animal):
...
giraffe = Giraffe()
feed_animal(giraffe)
abcтакже поддерживают неявные интерфейсы с помощью концепции « виртуальных подклассов ». Но вы должны вызывать registerдля каждой реализации:
class Giraffe: # no base class needed!
def eat(self, food) -> float:
return 0.
class Animal(ABC):
...
Animal.register(Giraffe) # achieves the same as implicit Protocol
Протоколы позволяют определить интерфейс для функции (не только класса) — см. протоколы обратного вызова . Это очень крутая функция, достойная отдельного поста.
Оба поддерживают методы по умолчанию (к сожалению)
abcИ у того, и у другого есть большой недостаток Protocols. В реальном мире многие люди работают с одной кодовой базой. Абстрактные базовые классы иногда имеют тенденцию приобретать реализации методов по умолчанию. Вот как это может выглядеть:
class Animal(Protocol): # the same holds for Animal(ABC):
def eat(self, food) -> float:
... # this is still abstract
def sleep(self, hours) -> float:
return 3.
Протоколы короче
И последнее, но не менее важное: вы можете подсчитать количество строк кода, необходимых для определения интерфейса. С abc, у вас должен быть abstractmethodдекоратор для каждого метода. Но с протоколами без проверки во время выполнения вам вообще не нужно использовать какие-либо декораторы. Так что здесь Протоколы побеждают безоговорочно.
Заключение
Складываем баллы:
Надеюсь, я не упустил ничего важного в этом анализе. Судя по результатам, команда «Протоколы» побеждает, и вам, наверное, стоит просто начать ее использовать!
Если вы нашли эту статью полезной, дайте мне несколько аплодисментов. Спасибо за чтение!
Вы можете найти меня в LinkedIn или Twitter .
Ресурсы
- Утиная печать вики
- Хороший учебник по уткопечатанию от Тейлора Мэндерсона.
- Аналогичное сравнение Zope и Protocols от Glyph
- Сравнение ABC и протоколов от Arjan
- Функциональные интерфейсы с протоколами обратного вызова
Повышение уровня кодирования
Спасибо, что являетесь частью нашего сообщества! Перед тем, как ты уйдешь:
- Хлопайте за историю и подписывайтесь на автора
- Смотрите больше контента в публикации Level Up Coding
- Подписывайтесь на нас: Твиттер | Линкедин | Новостная рассылка

![В любом случае, что такое связанный список? [Часть 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)



































