파이썬 추상 클래스에서 추상 속성을 만드는 방법


118

다음 코드에서는 기본 추상 클래스를 만듭니다 Base. 상속하는 모든 클래스가 속성 Base을 제공하기 를 원하므로이 name속성을 @abstractmethod.

그런 다음 일부 기능을 제공하지만 여전히 추상적 Base인이라는 하위 클래스를 만들었습니다 Base_1. 에는 name속성이 Base_1없지만 그럼에도 불구하고 파이썬은 오류없이 해당 클래스의 객체를 instatinates. 추상 속성을 어떻게 생성합니까?

from abc import ABCMeta, abstractmethod
class Base(object):
    __metaclass__ = ABCMeta
    def __init__(self, strDirConfig):
        self.strDirConfig = strDirConfig

    @abstractmethod
    def _doStuff(self, signals):
        pass

    @property    
    @abstractmethod
    def name(self):
        #this property will be supplied by the inheriting classes
        #individually
        pass


class Base_1(Base):
    __metaclass__ = ABCMeta
    # this class does not provide the name property, should raise an error
    def __init__(self, strDirConfig):
        super(Base_1, self).__init__(strDirConfig)

    def _doStuff(self, signals):
        print 'Base_1 does stuff'


class C(Base_1):
    @property
    def name(self):
        return 'class C'


if __name__ == '__main__':
    b1 = Base_1('abc')  

잡았다 : 당신은 장식을 사용하는 것을 잊지 경우 @propertyclass C, name방법으로 되돌아갑니다.
kevinarpe 2014

답변:


117

Python 3.3 이후 로 버그가 수정되어 property()추상 메서드에 적용될 때 데코레이터가 이제 추상으로 올바르게 식별됩니다.

주 : 주문 문제, 당신은 사용해야 @property하기 전에@abstractmethod

Python 3.3 이상 : ( python docs ) :

class C(ABC):
    @property
    @abstractmethod
    def my_abstract_property(self):
        ...

파이썬 2 : ( 파이썬 문서 )

class C(ABC):
    @abstractproperty
    def my_abstract_property(self):
        ...

1
@James 파이썬 2와 호환되도록 만드는 방법은 무엇입니까?
himanshu219 jul.

@ 제임스 실제로 나는 모두 의미하지만 신경 쓸 난 당신의 솔루션을 기반으로 대답을 게시
himanshu219

45

때까지 파이썬 3.3 , 당신은 중첩 할 수 없습니다 @abstractmethod@property.

@abstractproperty추상 속성 ( docs ) 을 만드는 데 사용 합니다 .

from abc import ABCMeta, abstractmethod, abstractproperty

class Base(object):
    # ...
    @abstractproperty
    def name(self):
        pass

이제 코드는 올바른 예외를 발생시킵니다.

역 추적 (가장 최근 호출 마지막) :
  파일 "foo.py", 36 행, 
    b1 = Base_1 ( 'abc')  
TypeError : 추상 메서드 이름으로 Base_1 추상 클래스를 인스턴스화 할 수 없습니다.

42
실제로이 대답은 어린 파이썬에게는 잘못되었습니다 .3.3 이후로 @abstractpropertyOP와 같은 조합을 위해 더 이상 사용되지 않습니다.
비행 양



3.3까지, 그냥raise NotImplementedError
Sławomir Lenart

객체에서 상속하고 여전히 ABC 주석을 사용할 수 있습니까? 예와 같이 작동합니까?
santhosh kumar

3

위의 James 답변을 기반으로

def compatibleabstractproperty(func):

    if sys.version_info > (3, 3):             
        return property(abstractmethod(func))
    else:
        return abstractproperty(func)

데코레이터로 사용

@compatibleabstractproperty
def env(self):
    raise NotImplementedError()
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.