`staticmethod`和`abc.abstractmethod`:它会融合吗?

时间:2010-12-17 20:11:39

标签: python abstract-class static-methods

在我的Python应用程序中,我想创建一个同时为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__'

4 个答案:

答案 0 :(得分:102)

Python 3.3 开始,它是possible to combine @staticmethod@abstractmethod,因此不再需要其他任何建议:

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

答案 1 :(得分:29)

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

答案 2 :(得分:12)

这样做:

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

更新 - 解释它的另一种方式:

方法是静态的,控制它的调用方式。 永远不会调用抽象方法。 因此,抽象静态方法是一个相当无意义的概念,除了文档目的。

答案 3 :(得分:4)

目前这在Python 2.X中是不可能的,它只会强制该方法是抽象的或静态的,但不能同时强制执行。

在Python 3.2+中,添加了新的装饰器abc.abstractclassmethodabc.abstractstaticmethod,以结合它们的抽象和静态或抽象的实现以及类方法。

请参阅Python Issue 5867