`staticmethod` 和 `abc.abstractmethod`:会融合吗?
Posted
技术标签:
【中文标题】`staticmethod` 和 `abc.abstractmethod`:会融合吗?【英文标题】:`staticmethod` and `abc.abstractmethod`: Will it blend? 【发布时间】:2011-05-27 08:10:22 【问题描述】:在我的 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:\Python26\Lib\abc.py", line 29, in abstractmethod
funcobj.__isabstractmethod__ = True
AttributeError: 'staticmethod' object has no attribute '__isabstractmethod__'
【问题讨论】:
【参考方案1】:从 Python 3.3 开始,它是 possible to combine @staticmethod
和 @abstractmethod
,因此不再需要其他建议:
@staticmethod
@abstractmethod
def my_abstract_staticmethod(...):
自version 3.3 以来,不推荐使用进一步的@abstractstatic
。
【讨论】:
注意你必须把@staticmethod
放在第一位,否则你会得到AttributeError: attribute '__isabstractmethod__' of 'staticmethod' objects is not writable
@property
相同
如果这是公认的答案,那将非常有帮助!
正是我想要的。谢谢!
是的,顺序很重要,如果你先写@abstractmethod,它就行不通了。【参考方案2】:
这样就可以了:
>>> 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】:这在 Python 2.X 中目前是不可能的,它只会强制方法是抽象的或静态的,而不是两者。
在 Python 3.2+ 中,添加了新的装饰器abc.abstractclassmethod
和 abc.abstractstaticmethod
以将它们强制执行为抽象和静态或抽象和类方法。
见Python Issue 5867
【讨论】:
虽然在 Python 3.2 中是新的,但abstractclassmethod
和 abstractstaticmethod
在 Python 3.3 以及 abstractproperty
中很快被弃用。 docs.python.org/3/library/abc.html
仅供参考:bugs.python.org/issue11610 描述了贬值,以及实现它的新方法......【参考方案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
【讨论】:
打得好,先生或女士 :-) 您在顶部漏掉了import abc
;以及显示 A 实例化的子类。(例如,class B(A):\n @staticmethod\n def test():\n print 10\n
)
我更新了代码以与子类化一起正常工作。 A.test 也应该有__isabstractmethod__
属性。
是否应该将abstractstatic
添加到abc.py
的上游?
abstractstaticmethod 自 3.3 版起已弃用:现在可以将 staticmethod 与 abstractmethod() 一起使用,从而使此装饰器变得多余。 link
抱歉 -1 没有添加任何解释以上是关于`staticmethod` 和 `abc.abstractmethod`:会融合吗?的主要内容,如果未能解决你的问题,请参考以下文章
当我需要在 python 编程中使用@staticmethod 和@classmethod 时? [复制]