2011-10-31 13 views
7

¿Qué pasa con el siguiente código (en Python 2.7.1):excepción de error debe derivar de BaseException incluso cuando lo hace (Python 2.7)

class TestFailed(BaseException): 
    def __new__(self, m): 
     self.message = m 
    def __str__(self): 
     return self.message 

try: 
    raise TestFailed('Oops') 
except TestFailed as x: 
    print x 

Cuando corro, me sale:

Traceback (most recent call last): 
    File "x.py", line 9, in <module> 
    raise TestFailed('Oops') 
TypeError: exceptions must be old-style classes or derived from BaseException, not NoneType 

Pero me parece que TestFailed deriva de BaseException.

+0

Para otras personas que no pueden entender por qué están recibiendo este error: comprobar para asegurarse de que no accidentalmente haces 'MiExcepción def (Excepción): pass' en lugar de la clase' requerido MiExcepción (Excepción): pase'. Error fácil de perder. –

Respuesta

9

__new__ es una métodoestático que debe devolver una instancia.

lugar, utilice el método __init__:

>>> class TestFailed(Exception): 
    def __init__(self, m): 
     self.message = m 
    def __str__(self): 
     return self.message 

>>> try: 
    raise TestFailed('Oops') 
except TestFailed as x: 
    print x 


Oops 
+0

Gracias (y a los demás que respondieron). Prefiero sospechar que fue algo simple (pero no tengo mucha experiencia con Python). –

4

Use __init__() en lugar de __new__() para "inicializar" las clases. En la mayoría de los casos, la anulación de __new__ no es necesaria. Se llama antes de __init__ durante la creación del objeto.

Ver también Python's use of __new__ and __init__?

2

La aplicación __new__ debe devolver una instancia de la clase, pero es momento de volver None (por defecto).

Sin embargo, parece que debe usar __init__ aquí, en lugar de __new__.

11

Otros le han mostrado cómo solucionar su implementación, pero creo que es importante señalar que el comportamiento que está implementando ya es el comportamiento estándar de excepciones en Python, por lo que la mayoría de su código es completamente innecesario. Solo derivar de Exception (la clase base apropiada para las excepciones de tiempo de ejecución) y poner pass como el cuerpo.

class TestFailed(Exception): 
    pass 
+0

Gracias por la información. No lo sabía. (En este caso particular, el código publicado aquí se simplifica, y mi '__init__' real tiene algunos argumentos adicionales. Pero definitivamente haré uso de su información en el futuro). –