Python `staticmethod` 和 `abc.abstractmethod`:它会融合吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4474395/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
`staticmethod` and `abc.abstractmethod`: Will it blend?
提问by Ram Rachum
In my Python app I want to make a method that is both a staticmethodand an abc.abstractmethod. How do I do this?
在我的 Python 应用程序中,我想创建一个既是 astaticmethod又是abc.abstractmethod. 我该怎么做呢?
I tried applying both decorators, but it doesn't work. If I do this:
我尝试应用两个装饰器,但它不起作用。如果我这样做:
import abc
class C(object):
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
@staticmethod
def my_function(): pass
I get an exception*, and if I do this:
我得到一个例外*,如果我这样做:
class C(object):
__metaclass__ = abc.ABCMeta
@staticmethod
@abc.abstractmethod
def my_function(): pass
The abstract method is not enforced.
不强制执行抽象方法。
How can I make an abstract static method?
如何创建抽象静态方法?
*The exception:
*例外:
File "c:\Python26\Lib\abc.py", line 29, in abstractmethod
funcobj.__isabstractmethod__ = True
AttributeError: 'staticmethod' object has no attribute '__isabstractmethod__'
采纳答案by Rosh Oxymoron
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
回答by Lennart Regebro
This will do it:
这将做到:
>>> 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
You go "Eh? It just renames @abstractmethod", and this is completely correct. Because any subclass of the above will have to include the @staticmethod decorator anyway. You have no need of it here, except as documentation when reading the code. A subclass would have to look like this:
你说“嗯?它只是重命名了@abstractmethod”,这是完全正确的。因为上面的任何子类都必须包含@staticmethod 装饰器。除了在阅读代码时作为文档之外,您在这里不需要它。子类必须如下所示:
>>> class B(A):
... @staticmethod
... def themethod():
... print "Do whatevs"
To have a function that would enforce you to make this method a static method you would have to subclass ABCmeta to check for that and enforce it. That's a lot of work for no real return. (If somebody forgets the @staticmethod decorator they will get a clear error anyway, it just won't mention static methods.
要拥有一个强制您将此方法设为静态方法的函数,您必须子类化 ABCmeta 以检查并强制执行它。这是很多没有真正回报的工作。(如果有人忘记了 @staticmethod 装饰器,他们无论如何都会得到一个明确的错误,只是不会提到静态方法。
So in fact this works just as well:
所以实际上这也同样有效:
>>> import abc
>>>
>>> class A(object):
... __metaclass__ = abc.ABCMeta
... @abc.abstractmethod
... def themethod():
... """Subclasses must implement this as a @staticmethod"""
... pass
Update - Another way to explain it:
更新 - 另一种解释方式:
That a method is static controls how it is called. An abstract method is never called. And abstract static method is therefore a pretty pointless concept, except for documentation purposes.
方法是静态的控制它的调用方式。永远不会调用抽象方法。因此,抽象静态方法是一个非常无意义的概念,除非用于文档目的。
回答by Nick
This is currently not possible in Python 2.X, which will only enforce the method to be abstract or static, but not both.
这在 Python 2.X 中目前是不可能的,它只会强制方法是抽象的或静态的,而不是两者兼而有之。
In Python 3.2+, the new decoratorsabc.abstractclassmethodand abc.abstractstaticmethodwere added to combine their enforcement of being abstract and static or abstract and a class method.
在 Python 3.2+ 中,添加了新的装饰器abc.abstractclassmethod和abc.abstractstaticmethod以结合它们的抽象和静态或抽象和类方法的强制执行。
回答by gerrit
Starting with Python 3.3, it is possible to combine@staticmethodand @abstractmethod, so none of the other suggestions are necessary anymore:
与开始的Python 3.3,它是可以组合@staticmethod和@abstractmethod,所以没有其他的建议是必要的了:
@staticmethod
@abstractmethod
def my_abstract_staticmethod(...):

