programing

static method와 abc.abstract method: 섞일까요?

abcjava 2023. 6. 15. 21:32
반응형

static method와 abc.abstract method: 섞일까요?

내 파이썬 앱에서 나는 둘 다인 방법을 만들고 싶습니다.staticmethod그리고. 이거 어떻게 하는 거예요?

저는 두 가지 장식품을 모두 적용해 보았지만 작동하지 않습니다.이 작업을 수행할 경우:

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__'

Python 3.3부터는 다음을 결합할 수 있습니다. @staticmethod그리고.@abstractmethod그래서 다른 제안들은 더 이상 필요하지 않습니다.

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

@abstractstatic버전 3.3 이후에는 더 이상 사용하지 않습니다.

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

이렇게 하면 됩니다.

  >>> 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

당신은 "에?그것은 단지 @추상적인 방법"이라는 이름을 바꿨을 뿐이고, 이것은 완전히 맞습니다.위의 모든 하위 클래스는 어쨌든 @static method decorator를 포함해야 하기 때문입니다.코드를 읽을 때 문서로 사용하는 경우를 제외하고는 여기에서 필요하지 않습니다.하위 클래스는 다음과 같아야 합니다.

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

이 메소드를 정적 메소드로 만드는 기능을 사용하려면 ABC 메타를 하위 클래스로 분류하여 확인하고 적용해야 합니다.실제 반품이 불가능한 작업입니다. (누군가가 @static method decorator를 잊어버린다면 어쨌든 명확한 오류가 발생할 것입니다. 정적인 방법은 언급되지 않을 것입니다.

그래서 사실 이것도 마찬가지로 작동합니다.

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

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

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

현재 Python 2.X에서는 이 방법을 추상적 또는 정적으로만 적용할 수 있지만 둘 다 적용할 수는 없습니다.

Python 3.2+의 새로운 데코레이터abc.abstractclassmethod그리고.abc.abstractstaticmethod추상적이고 정적이거나 추상적인 강제와 클래스 메소드를 결합하기 위해 추가되었습니다.

Python 문제 5867 참조

설명서는 다음과 같습니다.

언제abstractmethod()다른 메서드 설명자와 함께 적용되며, 가장 안쪽의 장식자로 적용되어야 합니다.

그렇게,@abstractmethod아래와 같이 가장 안쪽에 있는 장식가여야 합니다.

from abc import ABC, abstractmethod

class Person(ABC):

    @classmethod
    @abstractmethod # The innermost decorator
    def test1(cls):
        pass
    
    @staticmethod
    @abstractmethod # The innermost decorator
    def test2():
        pass

    @property
    @abstractmethod # The innermost decorator
    def name(self):
        pass

    @name.setter
    @abstractmethod # The innermost decorator
    def name(self, name):
        pass

    @name.deleter
    @abstractmethod # The innermost decorator
    def name(self):
        pass

그런 다음 하위 클래스에서 다음과 같이 재정의해야 합니다.

class Student(Person):
    
    def __init__(self, name):
        self._name = name
    
    @classmethod
    def test1(cls): # Overrides abstract class method
        print("Test1")
    
    @staticmethod
    def test2(): # Overrides abstract static method
        print("Test2")
    
    @property
    def name(self): # Overrides abstract getter
        return self._name
    
    @name.setter
    def name(self, name): # Overrides abstract setter
        self._name = name
    
    @name.deleter
    def name(self): # Overrides abstract deleter
        del self._name

그런 다음 하위 클래스를 인스턴스화하고 다음과 같이 호출할 수 있습니다.

obj = Student("John") # Instantiates "Student" class
obj.test1() # Class method
obj.test2() # Static method
print(obj.name) # Getter
obj.name = "Tom" # Setter
print(obj.name) # Getter
del obj.name # Deleter
print(hasattr(obj, "name"))

출력:

Test1
Test2
John 
Tom  
False

당신은 추상적인 속성에 대해 설명하는 제 대답을 볼 수 있습니다.

언급URL : https://stackoverflow.com/questions/4474395/staticmethod-and-abc-abstractmethod-will-it-blend

반응형