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

在我的Python应用程序中,我想创build一个既是staticmethod又是abc.abstractmethod方法的方法。 我该怎么做呢?

我尝试应用两个装饰器,但它不工作。 如果我这样做:

 import abc class C(object): __metaclass__ = abc.ABCMeta @abc.abstractmethod @staticmethod def my_function(): pass 

我得到一个exception*,如果我这样做:

 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__' 
 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 结合起来 ,所以没有其他build议是必要的了:

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

要有一个强制你使这个方法成为一个静态方法的函数,你必须inheritanceABCmeta来检查并强制执行它。 这是很多工作,没有真正的回报。 (如果有人忘记了@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.abstractclassmethodabc.abstractstaticmethod方法,将它们的抽象和静态或抽象的执行和类方法结合起来。

请参阅Python问题5867