`staticmethod` y` abc.abstractmethod`: ¿Se mezclará?

En mi aplicación Python quiero crear un método que sea tanto un staticmethod como un abc.abstractmethod . ¿Cómo hago esto?

Intenté aplicar ambos decoradores, pero no funciona. Si hago esto:

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

Obtengo una excepción *, y si hago esto:

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

El método abstracto no se aplica.

¿Cómo puedo hacer un método estático abstracto?

*La excepción:

 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 

A partir de Python 3.3 , es posible combinar @staticmethod y @abstractmethod , por lo que ya no son necesarias otras sugerencias:

 @staticmethod @abstractmethod def my_abstract_staticmethod(...): 

Esto lo hará:

  >>> 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  a = A() TypeError: Can't instantiate abstract class A with abstract methods test 

Ir “¿Eh? Simplemente cambia el nombre de @abstractmethod”, y esto es completamente correcto. Porque cualquier subclase de lo anterior tendrá que incluir el decorador @staticmethod de todos modos. No lo necesita aquí, excepto como documentación al leer el código. Una subclase tendría que verse así:

  >>> class B(A): ... @staticmethod ... def themethod(): ... print "Do whatevs" 

Para tener una función que le obligaría a hacer de este método un método estático, tendría que subclase ABCmeta para verificarlo y aplicarlo. Eso es mucho trabajo sin retorno real. (Si alguien olvida el decorador @staticmethod obtendrá un error claro de todos modos, simplemente no mencionará métodos estáticos.

Así que, de hecho, esto funciona igual de bien:

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

Actualización – Otra forma de explicarlo:

Que un método es estático controla cómo se llama. Un método abstracto nunca se llama. Y el método estático abstracto es, por lo tanto, un concepto bastante inútil, excepto con fines de documentación.

Actualmente, esto no es posible en Python 2.X, que solo impondrá que el método sea abstracto o estático, pero no ambos.

En Python 3.2+, se agregaron los nuevos decoradores abc.abstractclassmethod y abc.abstractstaticmethod para combinar su aplicación de ser abstracto y estático o abstracto y un método de clase.

Ver número de Python 5867