수색…


ABC 메타 메타 크라스 설정하기

추상 클래스는 상속되어야하지만 특정 메소드를 구현하지 않는 클래스이며 서브 클래스가 구현해야하는 메소드 서명 만 남겨 둡니다.

추상 클래스는 메소드 구현이 필요없이 유형화 된 언어의 인터페이스 개념과 비슷하게 클래스 추상화를 높은 수준에서 정의 및 시행하는 데 유용합니다.

추상 클래스를 정의하는 개념적 접근법 중 하나는 클래스 메소드를 스텁 (stub) 한 다음 액세스 할 경우 NotImplementedError를 발생시키는 것입니다. 이렇게하면 자식 클래스가 먼저 부모 클래스를 재정의하지 않고 부모 메서드에 액세스하지 못하게합니다. 이렇게 :

class Fruit:
    
    def check_ripeness(self):
        raise NotImplementedError("check_ripeness method not implemented!")


class Apple(Fruit):
    pass


a = Apple()
a.check_ripeness() # raises NotImplementedError

이런 식으로 추상 클래스를 생성하면 오버라이드되지 않는 메소드의 부적절한 사용을 막을 수 있으며, 확실히 메소드가 하위 클래스에서 정의되도록 권장하지만 정의를 강제하지는 않습니다. abc 모듈을 사용하면 부모 클래스와 조상 클래스의 추상 클래스 메서드를 무시할 때 하위 클래스가 인스턴스화되지 않도록 할 수 있습니다.

from abc import ABCMeta

class AbstractClass(object):
    # the metaclass attribute must always be set as a class variable 
    __metaclass__ = ABCMeta

   # the abstractmethod decorator registers this method as undefined
   @abstractmethod 
   def virtual_method_subclasses_must_define(self):
       # Can be left completely blank, or a base implementation can be provided
       # Note that ordinarily a blank interpretation implicitly returns `None`, 
       # but by registering, this behaviour is no longer enforced.

이제 하위 클래스를 만들고 재정의 할 수 있습니다.

class Subclass(AbstractClass):
    def virtual_method_subclasses_must_define(self):
        return

왜 / 어떻게 ABCMeta와 @abstractmethod를 사용 하는가?

추상 기본 클래스 (ABC)는 파생 클래스가 기본 클래스의 특정 메서드를 구현하는 것을 강제합니다.

이것이 어떻게 작동하고 왜 사용해야하는지 이해하려면 Van Rossum이 좋아할만한 예를 살펴 보겠습니다. 파생 된 모든 클래스에서 구현해야하는 두 가지 메소드 (농담 및 펀치 라인)가있는 Base 클래스 "MontyPython"이 있다고 가정 해 보겠습니다.

class MontyPython:
    def joke(self):
        raise NotImplementedError()

    def punchline(self):
        raise NotImplementedError()

class ArgumentClinic(MontyPython):
    def joke(self):
        return "Hahahahahah"

객체를 인스턴스화하고 두 가지 메소드를 호출하면 punchline() 메소드로 punchline() 예상대로) 오류가 발생합니다.

 >>> sketch = ArgumentClinic() 
 >>> sketch.punchline() 
NotImplementedError 

그러나 이것은 여전히 ​​오류없이 ArgumentClinic 클래스의 객체를 인스턴스화 할 수 있습니다. 실제로 punchline ()을 찾을 때까지는 오류가 발생하지 않습니다.

이는 ABC (Abstract Base Class) 모듈을 사용하여 피할 수 있습니다. 이 예제가 어떻게 작동하는지 살펴 보겠습니다.

from abc import ABCMeta, abstractmethod

class MontyPython(metaclass=ABCMeta):
    @abstractmethod
    def joke(self):
        pass

@abstractmethod
def punchline(self):
    pass

class ArgumentClinic(MontyPython):
    def joke(self):
        return "Hahahahahah"

이번에는 불완전한 클래스에서 객체를 인스턴스화하려고 할 때 즉시 TypeError가 발생합니다!

>>> c = ArgumentClinic()
TypeError:
"Can't instantiate abstract class ArgumentClinic with abstract methods punchline"

이 경우 모든 TypeErrors를 피하기 위해 클래스를 완성하는 것은 쉽습니다.

class ArgumentClinic(MontyPython):
    def joke(self):
        return "Hahahahahah"

    def punchline(self):
        return "Send in the constable!"

이번에는 객체를 인스턴스화하면 작동합니다!



Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow