`staticmethod` 및`abc.abstractmethod` : 혼합 될까요?


106

내 Python 앱에서 a staticmethodabc.abstractmethod. 어떻게해야합니까?

두 데코레이터를 모두 적용 해 보았지만 작동하지 않습니다. 이렇게하면 :

import abc

class C(object):
    __metaclass__ = abc.ABCMeta

    @abc.abstractmethod
    @staticmethod    
    def my_function(): pass

예외가 발생하고 * 이렇게하면 :

class C(object):
    __metaclass__ = abc.ABCMeta

    @staticmethod    
    @abc.abstractmethod
    def my_function(): pass

추상 방법은 적용되지 않습니다.

추상 정적 메서드를 어떻게 만들 수 있습니까?

* 예외 :

File "c:\Python26\Lib\abc.py", line 29, in abstractmethod
 funcobj.__isabstractmethod__ = True
AttributeError: 'staticmethod' object has no attribute '__isabstractmethod__'

5
수락 된 답변을 업데이트하십시오.
Neil G

답변:


34
class abstractstatic(staticmethod):
    __slots__ = ()
    def __init__(self, function):
        super(abstractstatic, self).__init__(function)
        function.__isabstractmethod__ = True
    __isabstractmethod__ = True

class A(object):
    __metaclass__ = abc.ABCMeta
    @abstractstatic
    def test():
        print 5

7
잘하셨습니다, 선생님 또는 부인 :-) 당신 import abc은 정상에서 빠졌습니다 ; 뿐만 아니라 서브 프로그램은 A. (예 인스턴스화 있음 class B(A):\n @staticmethod\n def test():\n print 10\n)
댄 브레 슬라

1
서브 클래 싱에서 제대로 작동하도록 코드를 업데이트했습니다. A.test에는 __isabstractmethod__속성 도 있어야 합니다.
Rosh Oxymoron

3
abstractstatic에 업스트림에 추가 해야합니까 abc.py?
nnyby

3
abstractstaticmethod 버전 3.3부터 폐지 : 이제 abstractmethod ()와 함께 staticmethod를 사용하여이 데코레이터를 중복시킬 수 있습니다. 링크
클리 khitarishvili

1
@iraklikhitarishvili 그래도 서브 클래스의 메서드를 정적으로 강요하지는 않습니다! staticmethod 데코레이터를 복제해야합니다 ... 그 주위에 방법이 없나요?
étale-cohomology

199

시작 파이썬 3.3 ,이다 결합하는 것이 가능 @staticmethod 하고 @abstractmethod, 다른 제안 중 어느 것도 더 이상 필요하지 않도록 :

@staticmethod
@abstractmethod
def my_abstract_staticmethod(...):

32
참고 당신은 넣어 가지고 @staticmethod같은 첫째, 또는 당신은 얻을 것이다AttributeError: attribute '__isabstractmethod__' of 'staticmethod' objects is not writable
마르코 술라에게

3
대한 동일은@property
zezollo

11
이것이 받아 들여진 대답이라면 정말 도움이 될 것입니다!
Keerthana Prabhakaran

내가 찾던 바로 그것. 감사!
shanu khera

13

이렇게하면됩니다.

  >>> import abc
  >>> abstractstaticmethod = abc.abstractmethod
  >>>
  >>> class A(object):
  ...     __metaclass__ = abc.ABCMeta
  ...     @abstractstaticmethod
  ...     def themethod():
  ...          pass
  ... 
  >>> a = A()
  >>> Traceback (most recent call last):
  File "asm.py", line 16, in <module>
    a = A()
  TypeError: Can't instantiate abstract class A with abstract methods test

"Eh? 그냥 @abstractmethod의 이름을 바꾼다"라고하면 완전히 맞습니다. 위의 모든 하위 클래스는 어쨌든 @staticmethod 데코레이터를 포함해야하기 때문입니다. 코드를 읽을 때 문서를 제외하고 여기에서는 필요하지 않습니다. 서브 클래스는 다음과 같아야합니다.

  >>> class B(A):
  ...     @staticmethod
  ...     def themethod():
  ...         print "Do whatevs"

이 메서드를 정적 메서드로 만들도록 강제하는 함수를 가지려면 ABCmeta를 하위 클래스로 분류하여이를 확인하고 적용해야합니다. 그것은 실제 수익이없는 많은 작업입니다. (누군가 @staticmethod 데코레이터를 잊어 버린 경우 어쨌든 명확한 오류가 발생하지만 정적 메서드는 언급하지 않습니다.

실제로 이것은 잘 작동합니다.

  >>> import abc
  >>>
  >>> class A(object):
  ...     __metaclass__ = abc.ABCMeta
  ...     @abc.abstractmethod
  ...     def themethod():
  ...         """Subclasses must implement this as a @staticmethod"""
  ...          pass

업데이트-설명하는 또 다른 방법 :

메서드가 정적이라는 것은 호출 방법을 제어합니다. 추상 메서드는 호출되지 않습니다. 따라서 추상 정적 방법은 문서화 목적을 제외하고는 매우 무의미한 개념입니다.


4

이것은 현재 Python 2.X에서 가능하지 않으며, 메서드를 추상 또는 정적으로 강제 할뿐 둘다는 아닙니다.

Python 3.2 이상에서 새로운 데코레이터 abc.abstractclassmethodabc.abstractstaticmethod 추상적이고 정적 또는 추상적이고 클래스 메소드 인 자신의 집행을 결합하는 추가되었습니다.

Python Issue 5867 참조


11
파이썬 3.2에서 새로운 동안 abstractclassmethod하고 abstractstaticmethod빠르게뿐만 아니라으로, 파이썬 3.3에서 사용되지 않는 abstractproperty. docs.python.org/3/library/abc.html
glarrain

4
참고 : bugs.python.org/issue11610헌신에 대해 설명하고이를 수행하는 새로운 방법 ...
FlipMcF 2013-08-01
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.