'staticmethod' и ' abc.abstractmethod`: будет ли это смесь?
в моем приложении Python я хочу сделать метод, который является одновременно staticmethod
и abc.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:Python26Libabc.py", line 29, in abstractmethod
funcobj.__isabstractmethod__ = True
AttributeError: 'staticmethod' object has no attribute '__isabstractmethod__'
4 ответа:
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
начиная с Python 3.3, это можно совместить
@staticmethod
и@abstractmethod
, поэтому никакие другие предложения больше не нужны:@staticmethod @abstractmethod def my_abstract_staticmethod(...):
это сделает это:
>>> 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
вы идете " а? Он просто переименовывает @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
обновление - еще один способ объяснить это:
что метод является статическим управляет тем, как он называется. Абстрактный метод никогда не вызывается. И поэтому абстрактный статический метод является довольно бессмысленной концепцией, за исключением документации цели.
в настоящее время это невозможно в Python 2.X, который только принудит метод быть абстрактным или статическим, но не обоими.
в Python 3.2+, новые декораторы
abc.abstractclassmethod
иabc.abstractstaticmethod
были добавлены, чтобы объединить их применение быть абстрактным и статическим или абстрактным и методом класса.посмотреть Python Выпуск 5867