개요
디자인 패턴을 공부하면서 구체화 되어 있는 것 보다 추상화된 것에 의존하라는 원칙(의존성 역전, Dependency Inversion)을 알게 되었다. 그러나 대부분의 디자인 패턴 포스트를 확인해보면 자바로 설명이 자주 쓰여있어서 필자는 Python에 추상 클래스가 없는지 궁금했다.
그리고 Python에도 추상 클래스가 있다는 사실!.. 그러나 기본적으로 제공되는 것은 아니다. (인터페이스는 지원하지 않음.)
일단 필자가 생각하는 추상 클래스의 필요성에 대해 말을 해보자면..
1. 특정 개념을 추상화 및 일반화하는데에 유리하고,
2. 추상 클래스에 속해 있는 추상 메소드는 반드시 구현(오버라이딩)을 해야하므로 개발자가 해당 추상 클래스를 사용할 때 추상 메소드를 구현하지 않고 넘어가는 실수를 방지할 수 있다는 점이다.
사용 예시
from abc import ABCMeta, ABC, abstractmethod
class MyABC(metaclass=ABCMeta):
@abstractmethod
def test_abstract_func(self):
pass
class SimpleMyABC(ABC):
@abstractmethod
def test_abstract_func(self):
pass
- 여기서 abc의 의미는 (abstract base class)의 약자이다. 그리고 위에서 언급한대로 추상 메소드는 반드시 비어있다. 왜냐하면 추상 클래스는 인스턴스화 시키기 위한 것이 아니기 때문이다. 반드시 상속을 받고 구현을 해야한다.
- ABCMeta는 추상 베이스 클래스(ABC)를 정의하기 위한 메타 클래스이다. ABCMeta 대신 ABC로 상속받아 추상 베이스 클래스를 정의할 수도 있다.
- (ABC를 상속받은) 추상 베이스 클래스는 register() 메소드가 정의되어 있다. 해당 메소드는 가상 서브 클래스로 등록될 수 있다.
- 등록된 가상 서브 클래스는 실제로 ABC를 상속받지 않았더라도 issubclass(subclass, ABC)와 isinstance(instance, ABC)에서 True로 인식된다.
- 등록된 서브클래스는 ABC의 실제 상속 계층(Method Resolution Order, MRO)에는 나타나지 않는다. 즉, ABC에 정의된 메서드가 자동으로 상속되거나 호출되는 것은 아니다.
- register()로 등록된 클래스가 ABC의 추상 메서드를 반드시 구현할 필요는 없다. 단지 타입 체크(예: isinstance, issubclass)에서만 ABC의 서브클래스로 간주된다.
- 추상 메소드 외에도 추상 정적 메소드 및 프로퍼티를 정의할 수 있다. (@abstractclassmethod, @abstractstaticmethod, @abstractproperty)
- (ABC를 상속받은) 추상 베이스 클래스는 register() 메소드가 정의되어 있다. 해당 메소드는 가상 서브 클래스로 등록될 수 있다.
from abc import *
class Device(metaclass=ABCMeta):
@abstractmethod
def get_device_info(self):
pass
@abstractmethod
def send_device_info(self):
pass
import requests
class Printer(Device)
def __init__(self):
self.url = ....
def get_device_info(self):
return type(self)
def send_device_info(self):
info = {'info': self.get_device_info}
requests.post(self.url, json=info)
- 먼저, ABCMeta 클래스를 상속받은 Device라는 추상 베이스 클래스를 정의한다.
- 해당 클래스에 get_device_info, send_device_info 추상 메소드를 정의한다. 구현은 하지 않는다.
- Printer 클래스에서 Device 추상 베이스 클래스를 상속받는다. 반드시 Device에서 정의한 추상 메소드(get_device_info, send_device_info)는 Printer 클래스에서 하나도 빠지지 않고 로직을 구현 및 오버라이딩 해야 한다.
'[Language] - Python' 카테고리의 다른 글
| property 데코레이터 (8) | 2021.02.02 |
|---|---|
| 덕 타이핑 (Duck Typing) (2) | 2020.12.29 |
| pickle 모듈 (0) | 2020.12.18 |
| 접근제한자 (Access Modifier) (0) | 2020.12.14 |
| 정적 메소드 staticmethod, classmethod, instancemethod (0) | 2020.12.09 |