2010-05-08 23 views
13

documentaciones Python states:Python: Excepción definida por el usuario que confirma la regla

Excepciones típicamente deben ser derivada de la clase de excepción, ya sea directamente o indirectamente.

la palabra 'typically' me deja en un estado ambiguo.

consideran el código:

class good(Exception): pass 
class bad(object): pass 

Heaven = good() 
Hell = bad() 

>>> raise Heaven 

Traceback (most recent call last): 
    File "<pyshell#163>", line 1, in <module> 
    raise Heaven 
good 

>>> raise Hell 

Traceback (most recent call last): 
    File "<pyshell#171>", line 1, in <module> 
    raise Hell 
TypeError: exceptions must be classes or instances, not bad 

por lo que cuando la lectura de los documentos de pitón, debo reemplazar 'typically' con ''?

¿Qué sucede si tengo una jerarquía de clases que no tiene nada que ver con la clase Excepción, y quiero 'subir' los objetos que pertenecen a la jerarquía?

puedo plantear siempre una excepción con un argumento:

raise Exception, Hell 

Esto parece un poco incómodo para mí

Lo que tiene de especial la excepción (EDIT: o BaseException) clase, que sólo sus miembros de la familia puede ser levantado?

+1

Más detalles sobre este requisito se pueden encontrar en http://www.python.org/dev/peps/pep-0352/ –

Respuesta

9

"¿Al leer los documentos de python, debo cambiar 'típicamente' con ''?"

Normalmente, se heredan de Excepción. Período. Eso es lo que dice.

A veces, puede heredar de BaseException. Eso es lo que no dice. Puede extender BaseExcetion porque quiere derrotar a los controladores except Exception.

¿Qué tiene de especial ...

Son subclases de BaseException. ¿Qué mas necesita saber? La fuente está disponible. Puede leer el código fuente de la declaración raise para ver exactamente lo que comprueba antes de arrojar el TypeError.

http://svn.python.org/view/python/trunk/Python/ceval.c?annotate=80817

Líneas de 3456 a 3563.

Sin embargo, lo único que importa de un stand-punto práctico es "subclases de BaseException."

0

Las cosas derivadas de las diferentes clases de error/excepción también pueden plantearse, pero generalmente están reservadas para otras cosas.

20

Existen otras clases válidas que puede heredar aparte de Exception, por ejemplo BaseException.

Consulte la documentación del exception hierarchy.

BaseException 
+-- SystemExit 
+-- KeyboardInterrupt 
+-- GeneratorExit 
+-- Exception 
     +-- StopIteration 
     +-- StandardError 
     etc.. 

En las versiones anteriores de Python, era posible lanzar cosas que no fueran excepciones. Por ejemplo en Python 2.5:

>>> raise "foo" 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
foo 

pero se obtiene esta advertencia desaprobación:

DeprecationWarning: raising a string exception is deprecated 

En las nuevas versiones esto no está permitido. Todo lo que levante debe derivar de BaseException.

3

'Normalmente' se utiliza porque hay unos pocos tipos muy raros de excepción que no quieren ser detectados por un controlador genérico Exception. Si tiene dudas herede de Exception, pero hay excepciones a esa regla.

La mayoría de las excepciones se utilizan para indicar algún tipo de error o condición excepcional que es el resultado del código y los datos. Estas excepciones son todas las subclases de Exception. Si desea plantear su propia excepción, probablemente pertenezca a esa categoría y, por lo tanto, también debe heredar Exception. Si desea un manejador de excepción genérico, p. para registrar errores, entonces es perfectamente razonable capturar Exception y esperar detectar cualquier error de esa manera.

Las otras excepciones que heredan directamente de BaseException son ligeramente diferentes. SystemExit se genera cuando llama al sys.exit() (o puede elevarlo directamente). Si tiene algún código de nivel superior que registra errores, entonces probablemente no desee que maneje el SystemExit de la misma manera. Solía ​​tener que incluir un controlador separado para SystemExit solo para detener el controlador genérico Exception que captura ese caso.

KeyboardInterrupt representa una condición inesperada, pero es una que se genera por la entrada externa del usuario por lo que puede ocurrir en cualquier parte de su código; no depende de ninguna manera del código o los datos. Eso significa que incluso si desea manejarlo, es probable que desee manejarlo de forma diferente a las excepciones que heredan de Exception.

0

A veces es posible que desee plantear cosas que no considera una excepción (sino la regla). Para estos casos excepcionales, uno puede considerar raise algo más que excepciones.

En un cálculo recursivo en el que en algún punto se encuentra una respuesta, elevarlo hacia el receptor que mira hacia arriba puede ser bastante ordenado (en lugar de return ing, lo que significa que la recursión tiene que esperar esto, pasarlo hacia arriba, etc. .).

Pero hoy en día solo pueden surgir clases antiguas (por razones de compatibilidad, supongo) y derivaciones de BaseException porque mucha gente abusa de cosas como cadenas de excepciones.

Cuestiones relacionadas