Java의 추상 클래스는 누구나 잘 알고 있습니다. Python에서는 abc 모듈을 사용하여 추상 클래스를 만들 수 있습니다. 여기에서는 Python에서 추상 클래스를 정의하고 사용하는 방법을 설명합니다.
Python은 java와 같습니다. 추상 클래스를 정의할 수도 있습니다.
추상 클래스에 대해 이야기하기 전에 먼저 추상 메서드 구현에 대해 이야기해 보겠습니다.
추상 메서드는 기본 클래스에 정의되어 있지만 구현이 없는 메서드입니다. Java에서는 메소드를 인터페이스로 선언할 수 있습니다. Python에서 추상 메서드를 구현하는 간단한 방법은 다음과 같습니다.
class Sheep(object): def get_size(self): raise NotImplementedError
Sheep에서 상속된 모든 하위 클래스는 get_size 메서드를 구현해야 합니다. 그렇지 않으면 오류가 생성됩니다. 하지만 이 구현 방법에는 단점이 있습니다. 정의된 하위 클래스는 해당 메서드가 호출될 때만 오류를 발생시킵니다. 클래스가 인스턴스화된 후 이를 트리거하는 간단한 방법은 다음과 같습니다. Python에서 제공하는 abc 모듈을 사용하십시오.
import abc class Sheep(object): __metaclass__ = abc.ABCMeta @abc.absractmethod def get_size(self): return
Sheep 클래스 또는 여기에서 상속된 하위 클래스를 인스턴스화할 때 예외가 발생합니다(get_size는 구현되지 않음).
따라서 추상 클래스를 정의하면 하위 클래스에 대한 공통 메서드를 정의할 수 있습니다(강제 구현).
추상 클래스 사용 방법
import abc class A(object): __metaclass__ = abc.ABCMeta @abc.abstractmethod def load(self, input): return @abc.abstractmethod def save(self, output, data): return
ABCMeta 메타클래스를 통해 추상 클래스를 만들려면 abstractmethod 데코레이터를 사용하세요. . 추상 메서드
가 구체적인 클래스를 등록함을 나타냅니다.
class B(object): def load(self, input): return input.read() def save(self, output, data): return output.write(data) A.register(B) if __name__ == '__main__': print issubclass(B, A) # print True print isinstance(B(), A) # print True
가 추상 클래스
하위 클래스 구현
class C(A): def load(self, input): return input.read() def save(self, output, data): return output.write(data) if __name__ == '__main__': print issubclass(C, A) # print True print isinstance(C(), A) # print True추상 클래스를 상속하는 방법을 사용하여 구체적인 클래스를 구현할 수 있습니다. 레지스터를 사용하지 마세요. 그러나 부작용은 기본 클래스를 통해 모든 구체적인 클래스를 찾을 수 있다는 것입니다
for sc in A.__subclasses__(): print sc.__name__ # print C상속을 사용하면 모든 구체적인 클래스를 찾을 수 있습니다. 그러나 레지스터를 사용하면 찾을 수 없습니다.
__subclasshook__ 사용
__subclasshook__을 사용한 후, 구체적인 클래스가 추상 클래스와 동일한 메서드를 정의하는 한, 하위 클래스로 간주됩니다
import abc class A(object): __metaclass__ = abc.ABCMeta @abc.abstractmethod def say(self): return 'say yeah' @classmethod def __subclasshook__(cls, C): if cls is A: if any("say" in B.__dict__ for B in C.__mro__): return True return NotTmplementd class B(object): def say(self): return 'hello' print issubclass(B, A) # True print isinstance(B(), A) # True print B.__dict__ # {'say': <function say at 0x7f...>, ...} print A.__subclasshook__(B) # True불완전한 구현
class D(A): def save(self, output, data): return output.write(data) if __name__ == '__main__': print issubclass(D, A) # print True print isinstance(D(), A) # raise TypeErrorD가 발생합니다. 불완전한 콘크리트 클래스를 구축하는 경우 추상 클래스 및 추상 메소드를 인스턴스화할 수 없습니다
추상 기본 클래스는 콘크리트 클래스에 사용됩니다
import abc from cStringIO import StringIO class A(object): __metaclass__ = abc.ABCMeta @abc.abstractmethod def retrieve_values(self, input): pirnt 'base class reading data' return input.read() class B(A): def retrieve_values(self, input): base_data = super(B, self).retrieve_values(input) print 'subclass sorting data' response = sorted(base_data.splitlines()) return response input = StringIO("""line one line two line three """) reader = B() print reader.retrieve_values(input)결과 인쇄
base class reading data subclass sorting data ['line one', 'line two', 'line three']super를 사용하여 추상 기본 클래스의 로직을 재사용할 수 있지만 하위 클래스에서 재정의 메서드를 제공해야 합니다.
추상 속성
import abc class A(object): __metaclass__ = abc.ABCMeta @abc.abstractproperty def value(self): return 'should never get here.' class B(A): @property def value(self): return 'concrete property.' try: a = A() print 'A.value', a.value except Exception, err: print 'Error: ', str(err) b = B() print 'B.value', b.value결과를 인쇄합니다. 추상 속성 getter 메서드가 하나만 있으므로 A를 인스턴스화할 수 없습니다.
Error: ... print concrete property
추상 읽기 및 쓰기 속성 정의
import abc class A(object): __metaclass__ = abc.ABCMeta def value_getter(self): return 'Should never see this.' def value_setter(self, value): return value = abc.abstractproperty(value_getter, value_setter) class B(A): @abc.abstractproperty def value(self): return 'read-only' class C(A): _value = 'default value' def value_getter(self): return self._value def value_setter(self, value): self._value = value value = property(value_getter, value_setter) try: a = A() print a.value except Exception, err: print str(err) try: b = B() print b.value except Exception, err: print str(err) c = C() print c.value c.value = 'hello' print c.value결과를 인쇄합니다. 이는 구체적인 클래스의 속성을 정의할 때 필요합니다. 추상 추상 속성과 동일합니다. 그 중 하나만 재정의하면 작동하지 않습니다.
error: ... error: ... print 'default value' print 'hello'읽기 및 쓰기를 위한 추상 속성을 구현하려면 데코레이터 구문을 사용하세요. 동일해야 합니다.
import abc class A(object): __metaclass__ = abc.ABCMeta @abc.abstractproperty def value(self): return 'should never see this.' @value.setter def value(self, _value): return class B(A): _value = 'default' @property def value(self): return self._value @value.setter def value(self, _value): self._value = _value b = B() print b.value # print 'default' b.value = 'hello' print b.value # print 'hello'