> 백엔드 개발 > 파이썬 튜토리얼 > Python에서 추상 클래스 정의 및 사용

Python에서 추상 클래스 정의 및 사용

高洛峰
풀어 주다: 2017-03-01 13:49:16
원래의
1481명이 탐색했습니다.

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__ == &#39;__main__&#39;:
  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 &#39;say yeah&#39;

  @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 &#39;hello&#39;

print issubclass(B, A)   # True
print isinstance(B(), A)  # True
print B.__dict__      # {&#39;say&#39;: <function say at 0x7f...>, ...}
print A.__subclasshook__(B) # True
로그인 후 복사

불완전한 구현

class D(A):
  def save(self, output, data):
    return output.write(data)

if __name__ == &#39;__main__&#39;:
  print issubclass(D, A)   # print True
  print isinstance(D(), A)  # raise TypeError
로그인 후 복사

D가 발생합니다. 불완전한 콘크리트 클래스를 구축하는 경우 추상 클래스 및 추상 메소드를 인스턴스화할 수 없습니다

추상 기본 클래스는 콘크리트 클래스에 사용됩니다

import abc 
from cStringIO import StringIO

class A(object):
  __metaclass__ = abc.ABCMeta

  @abc.abstractmethod
  def retrieve_values(self, input):
    pirnt &#39;base class reading data&#39;
    return input.read()


class B(A):

  def retrieve_values(self, input):
    base_data = super(B, self).retrieve_values(input)
    print &#39;subclass sorting data&#39;
    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
[&#39;line one&#39;, &#39;line two&#39;, &#39;line three&#39;]
로그인 후 복사

super를 사용하여 추상 기본 클래스의 로직을 재사용할 수 있지만 하위 클래스에서 재정의 메서드를 제공해야 합니다.

추상 속성

import abc

class A(object):
  __metaclass__ = abc.ABCMeta

  @abc.abstractproperty
  def value(self):
    return &#39;should never get here.&#39;

class B(A):
  
  @property
  def value(self):
    return &#39;concrete property.&#39;

try:
  a = A()
  print &#39;A.value&#39;, a.value
except Exception, err:
  print &#39;Error: &#39;, str(err)

b = B()
print &#39;B.value&#39;, b.value
로그인 후 복사

결과를 인쇄합니다. 추상 속성 getter 메서드가 하나만 있으므로 A를 인스턴스화할 수 없습니다.

Error: ...
print concrete property
로그인 후 복사

추상 읽기 및 쓰기 속성 정의

import abc

class A(object):
  __metaclass__ = abc.ABCMeta

  def value_getter(self):
    return &#39;Should never see this.&#39;

  def value_setter(self, value):
    return 

  value = abc.abstractproperty(value_getter, value_setter)

class B(A):
  
  @abc.abstractproperty
  def value(self):
    return &#39;read-only&#39;

class C(A):
  _value = &#39;default value&#39;

  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 = &#39;hello&#39;
print c.value
로그인 후 복사

결과를 인쇄합니다. 이는 구체적인 클래스의 속성을 정의할 때 필요합니다. 추상 추상 속성과 동일합니다. 그 중 하나만 재정의하면 작동하지 않습니다.

error: ...
error: ...
print &#39;default value&#39;
print &#39;hello&#39;
로그인 후 복사

읽기 및 쓰기를 위한 추상 속성을 구현하려면 데코레이터 구문을 사용하세요. 동일해야 합니다.

import abc

class A(object):
  __metaclass__ = abc.ABCMeta

  @abc.abstractproperty
  def value(self):
    return &#39;should never see this.&#39;

  @value.setter
  def value(self, _value):
    return 

class B(A):
  _value = &#39;default&#39;

  @property
  def value(self):
    return self._value

  @value.setter
  def value(self, _value):
    self._value = _value

b = B()
print b.value    # print &#39;default&#39;

b.value = &#39;hello&#39;
print b.value    # print &#39;hello&#39;
로그인 후 복사


Python에서 추상 클래스 정의 및 사용과 관련된 더 많은 기사를 보려면 다음 항목에 주의하세요. PHP 중국어 웹사이트!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿