Dans mon application Python je veux créer une méthode qui soit à la fois staticmethod
et abc.abstractmethod
. Comment puis-je faire cela?
J'ai essayé d'appliquer les deux décorateurs, mais cela ne fonctionne pas. Si je fais ça:
import abc
class C(object):
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
@staticmethod
def my_function(): pass
Je reçois une exception *, et si je fais cela:
class C(object):
__metaclass__ = abc.ABCMeta
@staticmethod
@abc.abstractmethod
def my_function(): pass
La méthode abstraite n'est pas appliquée.
Comment créer une méthode statique abstraite?
*L'éxéption:
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
En commençant par Python 3.3 , c'est possible de combiner@staticmethod
et @abstractmethod
, donc aucune des autres suggestions n'est plus nécessaire:
@staticmethod
@abstractmethod
def my_abstract_staticmethod(...):
Cela le fera:
>>> 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
Vous allez "Eh? Il renomme simplement @abstractmethod", et c'est tout à fait correct. Parce que toute sous-classe de ce qui précède devra de toute façon inclure le décorateur @staticmethod. Vous n'en avez pas besoin ici, sauf comme documentation lors de la lecture du code. Une sous-classe devrait ressembler à ceci:
>>> class B(A):
... @staticmethod
... def themethod():
... print "Do whatevs"
Pour avoir une fonction qui vous obligerait à faire de cette méthode une méthode statique, vous devez sous-classer ABCmeta pour vérifier cela et l'appliquer. C'est beaucoup de travail sans réel retour. (Si quelqu'un oublie le décorateur @staticmethod, il obtiendra une erreur claire de toute façon, cela ne mentionnera tout simplement pas les méthodes statiques.
Donc, en fait, cela fonctionne aussi bien:
>>> import abc
>>>
>>> class A(object):
... __metaclass__ = abc.ABCMeta
... @abc.abstractmethod
... def themethod():
... """Subclasses must implement this as a @staticmethod"""
... pass
Mise à jour - Une autre façon de l'expliquer:
Qu'une méthode soit statique contrôle comment elle est appelée. Une méthode abstraite n'est jamais appelée. Et la méthode statique abstraite est donc un concept assez inutile, sauf à des fins de documentation.
Ce n'est actuellement pas possible dans Python 2.X, qui imposera uniquement que la méthode soit abstraite ou statique, mais pas les deux.
Dans Python 3.2+, les nouveaux décorateursabc.abstractclassmethod
et abc.abstractstaticmethod
ont été ajoutés pour combiner leur application de l'abstrait et de la statique ou de l'abstrait et une méthode de classe.
Voir Problème Python 5867