pyplot python exception

python - pyplot - ¿Qué error levantar cuando el estado de la clase no es válido?



title plt python (6)

Considero que RuntimeError la más apropiada de todas las excepciones incorporadas para indicar un estado no válido.

Vea este ejemplo de cómo se usa en CPython:

Python 2.7.10 (default, Jul 13 2015, 12:05:58) [GCC 4.2.1 Compatible Apple LLVM 6.1.0 (clang-602.0.53)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> from threading import Thread >>> Thread().join() Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/local/Cellar/python/2.7.10_2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 938, in join raise RuntimeError("cannot join thread before it is started") RuntimeError: cannot join thread before it is started

Es importante notar que incluso la implementación de CPython en sí misma no es coherente con el uso de tipos de excepción específicos entre bibliotecas. A veces se usa ValueError su lugar, sin embargo, en mi opinión, su descripción de la documentación de Python muestra que su uso está reservado para otras situaciones. RuntimeError es una excepción más general y debe usarse cuando un fragmento de código no puede comportarse correctamente si se le dio una entrada adecuada, que es algo similar a la situación cuando un objeto se encuentra en un estado no válido.

En una clase de Python, ¿qué tipo de error debo provocar desde un método de instancia cuando algunos de los otros atributos de la clase deben cambiarse antes de ejecutar ese método?

Vengo de un fondo de C # en el que usaría InvalidOperationException , "la excepción que se produce cuando una llamada de método no es válida para el estado actual del objeto", pero no pude encontrar una excepción incorporada equivalente en Python .

He estado generando ValueError ("generado cuando una operación o función incorporada recibe un argumento que tiene el tipo correcto pero un valor inapropiado") cuando el problema está en los parámetros de la función. Supongo que esto es técnicamente un valor no válido para el parámetro self ; ¿Es esa la forma correcta de tratarlo? Por ejemplo, ¿es esto idiomático: raise ValueError("self.foo must be set before running self.bar()") ?


Creo que debería generar un ValueError cuando el problema está relacionado con los parámetros de la función, como lo está haciendo, y un AttributeError cuando el problema está con un atributo que debe configurarse.

Además, puede crear una subclase de AttributeError para hacer una excepción más específica, pero no lo veo necesario. La excepción AttributeError con su mensaje de error es suficientemente clara.


Creo que la forma pitónica no es dejar el objeto en un estado en el que una llamada de método no se bloquee a pesar de estar en un estado erróneo. Estos son los errores más difíciles de encontrar, ya que el punto donde finalmente se derrumba el programa no es donde ocurrió el error.

p.ej.

class PseudoTuple(object): """ The sum method of PseudoTuple will raise an AttributeError if either x or y have not been set """ def setX(self, x): self.x = x def setY(self, y): self.y = y def sum(self): """ In the documentation it should be made clear that x and y need to have been set for sum to work properly """ return self.x + self.y class AnotherPseudoTuple(PseudoTuple): """ For AnotherPseudoTuple sum will now raise a TypeError if x and y have not been properly set """ def __init__(self, x=None, y=None): self.x = x self.y = y

Lo que no se debe hacer es algo como

class BadPseudoTuple(PseudoTuple): """ In BadPseudoTuple -1 is used to indicate an invalid state """ def __init__(self, x=-1, y=-1): self.x = x self.y = y def sum(self): if self.x == -1 or self.y == -1: raise SomeException("BadPseudoTuple in invalid state") else: return self.x + self.y

Creo que esto viene bajo el lema de los pitones:

Es más fácil pedir perdón que obtener permiso

Si el estado excepcional es algo que puede esperarse que ocurra durante el curso normal de ejecución en lugar de ser un error del usuario al usar mal la clase, entonces parece razonable que cree su propia excepción. StopIteration y los iteradores son un ejemplo de esto.


ValueError es lo mejor que se puede plantear en este caso. Para Python, debería preferir usar los tipos de excepción incorporados en lugar de crear los suyos propios. Solo debe crear nuevos tipos de excepción cuando espera que necesite atraparla y comportarse de manera muy diferente a como se comportaría al capturar los tipos incorporados. En este caso, la situación no debería surgir; no espera detectarlo porque indicaría un error al utilizar la clase en cuestión. Para esto no vale la pena crear un nuevo tipo para que tenga otro nombre: para eso es la cadena de mensajes que le pasas a ValueError() .

¿Es posible reestructurar su clase para que un estado no válido no sea posible?


ValueError está bien para mí, pero creo que AssertionError es más apropiado. Básicamente, viola la aseveración hecha por el diseñador de la API.


class InvalidOperationException(Exception): pass SYS_STATE = 1 def something_being_run(): if SYS_STATE < 2: raise InvalidOperationException

Algo así que quieres decir? No veo ninguna razón por la que no debas hacer una subclase de excepción para crear tus propios tipos de Excepción, pero podría ser el antiguo Oracle PL / SQL Dev en mi salida ...