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

Ram*_*hum 86 python abstract-class static-methods

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

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

import abc

class C(object):
    __metaclass__ = abc.ABCMeta

    @abc.abstractmethod
    @staticmethod    
    def my_function(): pass
Run Code Online (Sandbox Code Playgroud)

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

class C(object):
    __metaclass__ = abc.ABCMeta

    @staticmethod    
    @abc.abstractmethod
    def my_function(): pass
Run Code Online (Sandbox Code Playgroud)

不强制执行抽象方法.

如何制作抽象静态方法?

*例外:

File "c:\Python26\Lib\abc.py", line 29, in abstractmethod
 funcobj.__isabstractmethod__ = True
AttributeError: 'staticmethod' object has no attribute '__isabstractmethod__'
Run Code Online (Sandbox Code Playgroud)

ger*_*rit 133

与开始的Python 3.3,它是可以组合 @staticmethod@abstractmethod,所以没有其他的建议是必要的了:

@staticmethod
@abstractmethod
def my_abstract_staticmethod(...):
Run Code Online (Sandbox Code Playgroud)

  • 请注意,您必须首先放置`@ staticmethod`,否则您将获得'staticmethod'对象的`AttributeError:attribute'__ isabstractmethod__'不可写 (20认同)
  • 如果这是接受的答案,那将是非常有帮助的! (5认同)
  • 同样适用于`@ property` (3认同)

Ros*_*ron 33

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
Run Code Online (Sandbox Code Playgroud)

  • 好玩,先生或女士:-)你在顶部省略了`import abc`; 以及显示A实例化的子类(例如,`class B(A):\n @staticmethod \n def test():\n print 10 \n`) (5认同)
  • 应该将`abstractstatic`添加到`abc.py`的上游吗? (3认同)
  • 对不起,因为没有添加任何解释而不得不-1 (3认同)
  • abstractstaticmethod从版本3.3开始不推荐使用:现在可以将staticmethod与abstractmethod()一起使用,使这个装饰器变得多余.[链接](https://docs.python.org/3/library/abc.html#abc.abstractstaticmethod) (2认同)

Len*_*bro 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
Run Code Online (Sandbox Code Playgroud)

你去"呃?它只是重命名@abstractmethod",这是完全正确的.因为上面的任何子类都必须包含@staticmethod装饰器.除了作为阅读代码的文档外,您在此处不需要它.子类必须如下所示:

  >>> class B(A):
  ...     @staticmethod
  ...     def themethod():
  ...         print "Do whatevs"
Run Code Online (Sandbox Code Playgroud)

要拥有一个强制您使此方法成为静态方法的函数,您必须继承ABCmeta以检查并强制执行该方法.没有真正的回报,这是很多工作.(如果有人忘了@staticmethod装饰器,他们会得到一个明确的错误,它只是不会提到静态方法.

所以事实上这也是有效的:

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

更新 - 另一种解释方式:

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


Nic*_*ick 6

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

在 Python 3.2+ 中,添加了新的装饰器abc.abstractclassmethod和 ,abc.abstractstaticmethod以将它们的抽象和静态或抽象和类方法的执行结合起来。

请参阅Python 问题 5867

  • 虽然“abstractclassmethod”和“abstractstaticmethod”是 Python 3.2 中的新增内容,但在 Python 3.3 中很快就被弃用了,“abstractproperty”也是如此。http://docs.python.org/3/library/abc.html (13认同)
  • 仅供参考:http://bugs.python.org/issue11610 描述了贬值以及新的方法...... (4认同)