¿Es convencional generar un NotImplementedError para métodos cuya implementación está pendiente, pero no se planea que sea abstracta?

34

Me gusta plantear un NotImplementedErrormétodo para cualquier método que quiera implementar, pero donde aún no he podido hacerlo. Es posible que ya tenga una implementación parcial, pero la antepongo raise NotImplementedError()porque todavía no me gusta. Por otro lado, también me gusta apegarme a las convenciones, porque esto facilitará que otras personas mantengan mi código, y las convenciones pueden existir por una buena razón.

Sin embargo, la documentación de Pythons para NotImplementedError establece:

Esta excepción se deriva de RuntimeError. En las clases base definidas por el usuario, los métodos abstractos deberían generar esta excepción cuando requieren clases derivadas para anular el método.

Ese es un caso de uso formal mucho más específico que el que describo. ¿Es un buen estilo convencional plantear NotImplementedErrorsimplemente para indicar que esta parte de la API es un trabajo en progreso? Si no, ¿hay una forma estandarizada diferente de indicar esto?

gerrit
fuente
¿Qué quieres decir con "apropiado"?
Robert Harvey
1
@RobertHarvey Supongo que me refiero a convencional, después de un uso común. He reformulado mi pregunta ahora.
Gerrit
1
Usamos C # aquí principalmente, pero ese tipo de lanzamiento de excepciones es idiomático aquí, y esperaría en otro lado. Descansar temprano y hacerlo en voz alta es una buena guía para identificar problemas potenciales rápidamente (léase: a bajo costo).
Telastyn
En general, si estoy creando una clase, solo pongo TODO comentarios en métodos no implementados hasta que llego a implementar la funcionalidad. Si la clase fuera lanzada a producción antes de que eso sucediera, consideraría lanzar excepciones.
55
Por lo que vale, esto es lo que Microsoft Visual Studio hace de manera predeterminada cuando usa el IDE para "implementar una interfaz". Según Robert Harvey, el resultado se entiende bien.
comida para gatos

Respuestas:

34

Vale la pena señalar que, si bien la documentación de Python proporciona un caso de uso (y probablemente el canónico) para esta excepción, no excluye específicamente su uso en otros escenarios.

Consideraría apropiado generar una excepción NotImplementedError si aún no ha anulado un método en una clase base (para satisfacer la "interfaz").

Una verificación superficial en Google sugiere que las personas entenderán lo que quieres decir si usas la excepción de esta manera. No hay efectos secundarios o consecuencias involuntarias que yo sepa; el método simplemente arrojará una excepción si se llama, y ​​arrojará una excepción que todos entiendan bien.


La documentación para Python 3 refleja este uso exacto:

En las clases base definidas por el usuario, los métodos abstractos deberían generar esta excepción cuando requieren que las clases derivadas anulen el método, o mientras se desarrolla la clase para indicar que la implementación real todavía necesita ser agregada . [Énfasis añadido]

Robert Harvey
fuente
+1, pero también agregaría que para este tipo de convención, un poco de documentación puede ser muy útil. Como una nota de una línea en un wiki de desarrollo, un archivo readme o una guía de estilo, algo así, que explique para qué utiliza esta excepción.
Ben Lee
8

Esto se entenderá, ya sea que lo haga o no debe depender de las convenciones locales (de equipo o empresa). Tenga en cuenta que tiene menos sentido en el contexto de TDD, ya que la PRUEBA debe ser lo que determina que el método no se implementa.

La versión corta es: úsela si usted y su equipo lo consideran apropiado.

jmoreno
fuente
55
FWIW, Lanzar la excepción debería ser una buena manera de hacer que la prueba falle, si por alguna razón necesita forzar ese comportamiento. (Sería útil como parte de un stub intellisense de definición de método, por ejemplo.)
DougM
1

Parece que NotImplementedErrorgeneralmente se está generando para los desarrollos de características de Python, como el siguiente:

@classmethod
def fromkeys(cls, iterable, v=None):
    # There is no equivalent method for counters because setting v=1
    # means that no element can have a count greater than one.
    raise NotImplementedError(
        'Counter.fromkeys() is undefined.  Use Counter(iterable) instead.')

Documetation

fromkeys (iterable)

Este método de clase no está implementado para objetos Counter.

Fuente

Collections.Counter.fromkeys

Emma
fuente