Python 인터페이스: ABC보다 프로토콜 선택
새롭고 반짝이는 프로토콜을 선호하는 몇 가지 실용적인 이유
abc저는 지난 10년 동안 표준 Python 라이브러리를 사용하여 인터페이스를 정의했습니다. 하지만 최근에는 상대적으로 새로운 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
둘 다 명시적 구문을 지원합니다.
첫째, 여전히 명시적으로 an abc 및 a 에서 상속할 수 있습니다 Protocol. Arjan 의 아주 좋은 비디오 (및 댓글) 의 많은 주장은 프로토콜로는 그렇게 할 수 없다는 오해를 중심으로 전개됩니다. 당신은 완전히 할 수 있습니다:
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그러나 런타임 검사가 없는 프로토콜을 사용하면 데코레이터를 전혀 사용할 필요가 없습니다. 그래서 여기에서 프로토콜이 승리합니다.
결론
점수를 합산해 보겠습니다.
바라건대, 나는 이 분석에서 큰 것을 놓치고 있지 않습니다. 결과를 보면 "Protocols" 팀이 이겼고, 아마도 그것을 사용하기 시작해야 할 것입니다!
이 글이 도움이 되셨다면 박수 한 번 부탁드립니다. 읽어 주셔서 감사합니다!
LinkedIn 또는 Twitter 에서 저를 찾을 수 있습니다 .
자원
- 오리 타이핑 위키
- Taylor Manderson의 좋은 오리 타이핑 튜토리얼
- Zope와 Glyph의 프로토콜 간의 유사한 비교
- Arjan의 ABC 대 프로토콜 비교
- 콜백 프로토콜이 있는 기능적 인터페이스
레벨업 코딩
우리 커뮤니티의 일원이 되어 주셔서 감사합니다! 가기 전에:
- 이야기에 박수치고 작가 팔로우
- 레벨업 코딩 출판물 에서 더 많은 콘텐츠 보기
- 팔로우: 트위터 | 링크드인 | 뉴스 레터

![연결된 목록이란 무엇입니까? [1 부]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)



































