WeniVooks

검색

견고한 파이썬

추상 클래스와 인터페이스

1. 추상 클래스

"만약 메타클래스가 필요한지 궁금하다면, 이건 필요하지 않다는 의미입니다." - 파이썬 선의 저자 팀 파터스

메타클래스는 견고한 파이썬에서도 다루지 않습니다. 팀 피터스는 99%의 경우 메타클래스가 필요없다고 얘기하였습니다. 추상클래스 또한 마찬가지입니다. 대부분의 파이썬 사용자에게 해당 내용은 필요하지 않습니다. 필요한 경우에 찾아보시길 바랍니다.

파이썬에서 추상 클래스(Abstract Base Class, ABC)는 기본적으로 구현하지 않아도 되는 메서드(추상 메서드)를 가진 클래스입니다. 이들은 서브클래스에서 반드시 구현해야 하는 메서드를 정의하는데 사용됩니다. abc 모듈의 ABC 클래스와 abstractmethod 데코레이터를 사용하여 추상 클래스와 추상 메서드를 정의합니다.

아래와 같이 추상 클래스에 do_something을 정의해놓고 만약 이 클래스를 상속하는 클래스에서 해당 메서드를 재정의하지 않으면 에러가 납니다.

from abc import ABC, abstractmethod class AbstractClassExample(ABC): @abstractmethod def do_something(self): pass class Person(AbstractClassExample): def __init__(self, name): self.name = name def print_name(self): print(f'제 이름은 {self.name}입니다.') hojun = Person('hojun') hojun.print_name()
# 출력
---------------------------
TypeError Traceback (most recent call last)
<ipython-input-34-15cbe4aeb172> in <cell line: 17>()
     16
---> 17 hojun = Person('hojun')
     18 hojun.print_name()

TypeError: Can't instantiate abstract 
class Person with abstract method do_something
# 출력
---------------------------
TypeError Traceback (most recent call last)
<ipython-input-34-15cbe4aeb172> in <cell line: 17>()
     16
---> 17 hojun = Person('hojun')
     18 hojun.print_name()

TypeError: Can't instantiate abstract 
class Person with abstract method do_something

아래와 같이 추상 클래스에 선언된 메서드를 자식 클래스에서 오버라이딩(재정의)하여 사용해야 합니다.

from abc import ABC, abstractmethod class AbstractClassExample(ABC): @abstractmethod def do_something(self): pass class Person(AbstractClassExample): def __init__(self, name): self.name = name def print_name(self): print(f'제 이름은 {self.name}입니다.') def do_something(self): pass hojun = Person('Jun') hojun.print_name()
# 출력
제 이름은 Jun입니다.
# 출력
제 이름은 Jun입니다.

2. 인터페이스

인터페이스는 객체가 어떤 메서드를 구현해야 하는지 정의한 것입니다. Python에서는 다른 언어들과 달리 인터페이스라는 내장 키워드나 구조가 없습니다. 그러나 추상 클래스를 이용하여 인터페이스처럼 동작하는 클래스를 만들 수 있습니다. 이렇게 추상 클래스로 이를 상속받은 클래스가 특정 메서드를 구현하게 강제함으로써 구조적인 특징을 가질 수 있도록 합니다.

from abc import ABC, abstractmethod
 
class MyInterface(ABC):
 
    @abstractmethod
    def method1(self):
        pass
 
    @abstractmethod
    def method2(self):
        pass
from abc import ABC, abstractmethod
 
class MyInterface(ABC):
 
    @abstractmethod
    def method1(self):
        pass
 
    @abstractmethod
    def method2(self):
        pass

Python에 기본 라이브러리를 확인하면 이러한 추상 클래스들이 어떻게 사용되는지 확인할 수 있습니다. 아래 폴더에서 기본적으로 내장되어 있는 라이브러리들을 확인할 수 있습니다. 이 설치 경로는 OS에 따라 다릅니다. Lib > importlib > abc.py와 같은 파일을 확인해보면 추상 클래스가 어떻게 사용되는지 확인할 수 있습니다.

class Finder(metaclass=abc.ABCMeta):
 
    """Legacy abstract base class for import finders.
 
    It may be subclassed for compatibility with legacy third party
    reimplementations of the import system.  Otherwise, finder
    implementations should derive from the more specific MetaPathFinder
    or PathEntryFinder ABCs.
 
    Deprecated since Python 3.3
    """
 
    def __init__(self):
        warnings.warn("the Finder ABC is deprecated and "
                       "slated for removal in Python 3.12; use MetaPathFinder "
                       "or PathEntryFinder instead",
                       DeprecationWarning)
 
    @abc.abstractmethod
    def find_module(self, fullname, path=None):
        """An abstract method that should find a module.
        The fullname is a str and the optional path is a str or None.
        Returns a Loader object or None.
        """
        warnings.warn("importlib.abc.Finder along with its find_module() "
                      "method are deprecated and "
                       "slated for removal in Python 3.12; use "
                       "MetaPathFinder.find_spec() or "
                       "PathEntryFinder.find_spec() instead",
                       DeprecationWarning)
class Finder(metaclass=abc.ABCMeta):
 
    """Legacy abstract base class for import finders.
 
    It may be subclassed for compatibility with legacy third party
    reimplementations of the import system.  Otherwise, finder
    implementations should derive from the more specific MetaPathFinder
    or PathEntryFinder ABCs.
 
    Deprecated since Python 3.3
    """
 
    def __init__(self):
        warnings.warn("the Finder ABC is deprecated and "
                       "slated for removal in Python 3.12; use MetaPathFinder "
                       "or PathEntryFinder instead",
                       DeprecationWarning)
 
    @abc.abstractmethod
    def find_module(self, fullname, path=None):
        """An abstract method that should find a module.
        The fullname is a str and the optional path is a str or None.
        Returns a Loader object or None.
        """
        warnings.warn("importlib.abc.Finder along with its find_module() "
                      "method are deprecated and "
                       "slated for removal in Python 3.12; use "
                       "MetaPathFinder.find_spec() or "
                       "PathEntryFinder.find_spec() instead",
                       DeprecationWarning)
{"packages":["numpy","pandas","matplotlib","lxml"]}
10.8 메서드 오버라이딩10.10 비공개 속성