source

Python의 추상 클래스와 인터페이스의 차이

manycodes 2022. 11. 5. 09:02
반응형

Python의 추상 클래스와 인터페이스의 차이

파이썬의 추상 클래스와 인터페이스의 차이점은 무엇입니까?

다음과 같은 경우가 있습니다.

class Abstract1:
    """Some description that tells you it's abstract,
    often listing the methods you're expected to supply."""

    def aMethod(self):
        raise NotImplementedError("Should have implemented this")

Python은 공식적인 인터페이스 계약을 가지고 있지 않기 때문에 (그리고 필요하지 않기 때문에) 추상화와 인터페이스의 자바 스타일의 구별은 존재하지 않습니다.누군가가 정식 인터페이스를 정의하기 위해 노력한다면, 그 또한 추상적인 클래스가 될 것입니다.유일한 차이점은 문서 문자열에 명시된 의도일 것입니다.

오리타입을 할 때 추상적인 것과 인터페이스적인 것의 차이는 사소한 것입니다.

Java는 다중 상속이 없기 때문에 인터페이스를 사용합니다.

Python은 여러 개의 상속을 가지고 있기 때문에 다음과 같은 것도 볼 수 있습니다.

class SomeAbstraction:
    pass  # lots of stuff - but missing something

class Mixin1:
    def something(self):
        pass  # one implementation

class Mixin2:
    def something(self):
        pass  # another

class Concrete1(SomeAbstraction, Mixin1):
    pass

class Concrete2(SomeAbstraction, Mixin2):
    pass

이것은 mixin을 포함한 추상적인 슈퍼클래스를 사용하여 분리된 구체적인 서브클래스를 만듭니다.

파이썬의 추상 클래스와 인터페이스의 차이점은 무엇입니까?

오브젝트의 인터페이스는 그 오브젝트상의 메서드 및 Atribute 세트입니다.

Python에서는 추상 기본 클래스를 사용하여 인터페이스를 정의하고 적용할 수 있습니다.

Abstract 기본 클래스 사용

를 들어, 추상 중 .collections★★★★

import collections
class MySet(collections.Set):
    pass

하면 ''가 요.TypeError작성한 클래스가 다음 세트의 예상되는 동작을 지원하지 않기 때문입니다.

>>> MySet()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class MySet with abstract methods
__contains__, __iter__, __len__

이 때문에, 우리는 적어도 __contains__,__iter__ , , , , 입니다.__len__매뉴얼에 기재되어 있는 다음 구현 예를 사용합니다.

class ListBasedSet(collections.Set):
    """Alternate set implementation favoring space over speed
    and not requiring the set elements to be hashable. 
    """
    def __init__(self, iterable):
        self.elements = lst = []
        for value in iterable:
            if value not in lst:
                lst.append(value)
    def __iter__(self):
        return iter(self.elements)
    def __contains__(self, value):
        return value in self.elements
    def __len__(self):
        return len(self.elements)

s1 = ListBasedSet('abcdef')
s2 = ListBasedSet('defghi')
overlap = s1 & s2

구현:Abstract 기본 클래스 만들기

Base Class로 하면 독자적인 Abstract 수 .abc.ABCMeta 을 합니다.abc.abstractmethod데코레이터를 소개합니다.된다.__abstractmethods__속성: 의될될 at at at at at at at at at at at at at at.

import abc

예를 들어, "effable"은 말로 표현할 수 있는 것으로 정의된다.예를 들어 Python 2에서 삭제 가능한 추상 기본 클래스를 정의하려고 합니다.

class Effable(object):
    __metaclass__ = abc.ABCMeta
    @abc.abstractmethod
    def __str__(self):
        raise NotImplementedError('users must define __str__ to use this base class')

또는 메타클래스 선언이 약간 변경된 Python 3의 경우:

class Effable(object, metaclass=abc.ABCMeta):
    @abc.abstractmethod
    def __str__(self):
        raise NotImplementedError('users must define __str__ to use this base class')

인터페이스를 실장하지 않고 삭제 가능한 오브젝트를 작성하려고 하면 다음과 같이 됩니다.

class MyEffable(Effable): 
    pass

인스턴스화를 시도합니다.

>>> MyEffable()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class MyEffable with abstract methods __str__

우리는 그 일을 끝내지 못했다고 들었다.

다음으로 예상되는 인터페이스를 제공하여 준거할 경우:

class MyEffable(Effable): 
    def __str__(self):
        return 'expressable!'

다음으로 추상적인 클래스에서 파생된 구체적인 버전을 사용할 수 있습니다.

>>> me = MyEffable()
>>> print(me)
expressable!

이 밖에도 이러한 인터페이스를 이미 구현한 가상 서브클래스를 등록하는 등 할 수 있는 일이 있습니다만, 이 질문의 범위 밖이라고 생각합니다.은 이 .abc 모듈에서는 할 수 있습니다.

결론

Abstract Base Class를 만들면 Python에서 커스텀 객체에 대한 인터페이스가 정의된다는 것을 증명했습니다.

Python > = 2.6에는 Abstract 기본 클래스가 있습니다.

Abstract Base Class(약칭 ABC)는 hasattr()와 같은 다른 기술이 서툴 때 인터페이스를 정의하는 방법을 제공함으로써 duck-type을 보완합니다.Python에는 데이터 구조(수집 모듈), 숫자(숫자 모듈) 및 스트림(IO 모듈)에 대한 많은 기본 제공 ABC가 포함되어 있습니다.abc 모듈을 사용하여 독자적인 ABC를 작성할 수 있습니다.

Zope Interface 모듈도 있는데, Zope 이외의 프로젝트에서 트위스트처럼 사용됩니다.잘 모르지만 도움이 될만한 위키페이지가 있어요

일반적으로 추상 클래스나 python 인터페이스(편집자: S 참조)의 개념은 필요하지 않습니다.자세한 내용은 Lott의 답변).

보다 기본적인 설명:인터페이스는 일종의 빈 머핀 팬과 같습니다.코드 없는 메서드 정의 집합이 있는 클래스 파일입니다.

추상 클래스는 동일하지만 모든 함수가 비어 있을 필요는 없습니다.코드를 가진 사람도 있습니다.엄밀히 말하면 비어있지 않아요.

차별화 이유:Python에는 실제적인 차이가 별로 없지만, 대규모 프로젝트에서는 코드가 없기 때문에 인터페이스에 대해 이야기하는 것이 더 일반적일 수 있습니다.특히 이 용어에 익숙한 자바 프로그래머와 함께 작업하는 경우에는 더욱 그렇습니다.

Python은 사실 어느 개념도 가지고 있지 않다.

duck typing을 사용하여 인터페이스(최소한 컴퓨터:-)의 필요성을 없앴습니다.

Python <= 2.5: 기본 클래스는 분명히 존재하지만 메서드를 '순수한 가상'으로 표시할 수 있는 명시적인 방법이 없기 때문에 클래스는 추상적이지 않습니다.

Python > = 2.6: 추상 기본 클래스가 존재합니다(http://docs.python.org/library/abc.html).또한 하위 클래스에서 구현해야 하는 메서드를 지정할 수 있습니다.구문은 별로 마음에 들지 않지만, 기능은 거기에 있습니다.대부분의 경우 '사용' 클라이언트 측에서 오리타입을 사용하는 것이 좋습니다.

일반적으로 인터페이스는 단일 상속 클래스 모델을 사용하는 언어에서만 사용됩니다.이러한 단일 상속 언어에서는 일반적으로 클래스가 특정 메서드 또는 메서드 세트를 사용할 수 있는 경우 인터페이스가 사용됩니다.또한 이러한 단일 상속 언어에서 추상 클래스는 하나 이상의 메서드 외에 클래스 변수를 정의하거나 단일 상속 모델을 이용하여 메서드 집합을 사용할 수 있는 클래스의 범위를 제한하기 위해 사용됩니다.

다중 상속 모델을 지원하는 언어는 인터페이스가 아닌 클래스 또는 추상 기본 클래스만 사용하는 경향이 있습니다.Python은 다중 상속을 지원하므로 인터페이스를 사용하지 않으며 기본 클래스 또는 추상 기본 클래스를 사용할 수 있습니다.

http://docs.python.org/library/abc.html

추상 클래스는 하나 이상의 추상 메서드를 포함하는 클래스입니다.추상 클래스는 추상 메서드와 함께 정적 메서드, 클래스 메서드 및 인스턴스 메서드를 가질 수 있습니다.단, 인터페이스의 경우 추상적인 메서드만 포함되며 다른 메서드는 없습니다.따라서 추상 클래스를 상속할 필요는 없지만 인터페이스를 상속할 필요가 있습니다.

완전성을 위해 ABC가 도입된 PEP3119와 인터페이스와의 비교, 그리고 원래의 Talin의 코멘트를 언급해야 한다.

추상 클래스는 완벽한 인터페이스가 아닙니다.

  • 상속 계층에 속함
  • 변동 가능

하지만 당신만의 방식으로 쓰는 것을 고려한다면:

def some_function(self):
     raise NotImplementedError()

interface = type(
    'your_interface', (object,),
    {'extra_func': some_function,
     '__slots__': ['extra_func', ...]
     ...
     '__instancecheck__': your_instance_checker,
     '__subclasscheck__': your_subclass_checker
     ...
    }
)

ok, rather as a class
or as a metaclass
and fighting with python to achieve the immutable object
and doing refactoring
...

여러분은 여러분이 결국 성취할 수 있는 바퀴를 발명하고 있다는 것을 금방 깨닫게 될 것입니다.abc.ABCMeta

abc.ABCMeta없어진 인터페이스 기능의 유용한 추가로서 제안되었습니다.이것은 python과 같은 언어에서는 충분히 공평합니다.

확실히 버전 3을 작성하고 새로운 구문과 불변의 인터페이스 개념을 추가하는 동안 더 잘 확장할 수 있었습니다.

결론:

The abc.ABCMeta IS "pythonic" interface in python

언급URL : https://stackoverflow.com/questions/372042/difference-between-abstract-class-and-interface-in-python

반응형