example - python exceptions list
BaseException.message obsoleto en Python 2.6 (8)
Recibo una advertencia de que BaseException.message está en desuso en Python 2.6 cuando utilizo la siguiente excepción definida por el usuario:
class MyException(Exception):
def __init__(self, message):
self.message = message
def __str__(self):
return repr(self.message)
Esta es la advertencia:
DeprecationWarning: BaseException.message has been deprecated as of Python 2.6
self.message = message
¿Qué pasa con esto? ¿Qué tengo que cambiar para deshacerme de la advertencia de desaprobación?
Cómo replicar la advertencia
Permítanme aclarar el problema, ya que uno no puede replicar esto con el código de muestra de la pregunta, esto replicará la advertencia:
>>> error = Exception(''foobarbaz'')
>>> error.message
__main__:1: DeprecationWarning: BaseException.message has been deprecated as of Python 2.6
''foobarbaz''
Eliminando la advertencia mientras aún usas .message
Y la forma de deshacerse de DeprecationWarning
es subclasificar una excepción incorporada, como pretendían los diseñadores de Python:
class MyException(Exception):
def __init__(self, message, *args):
self.message = message
# delegate the rest of initialization to parent
super(MyException, self).__init__(message, *args)
>>> myexception = MyException(''my message'')
>>> myexception.message
''my message''
>>> str(myexception)
''my message''
>>> repr(myexception)
"MyException(''my message'',)"
Alternativamente, evite el atributo .message
Sin embargo, probablemente sea preferible evitar el atributo de mensaje para comenzar y simplemente tomar el str
del error. Exception
subclase Just:
class MyException(Exception):
''''''demo straight subclass''''''
Y el uso:
>>> myexception = MyException(''my message'')
>>> str(myexception)
''my message''
Ver también esta respuesta:
¿La forma correcta de declarar excepciones personalizadas en Python moderno?
Solución: casi no se necesita codificación
Simplemente herede su clase de Exception
de Exception
y pase el mensaje como el primer parámetro al constructor
Ejemplo:
class MyException(Exception):
"""My documentation"""
try:
raise MyException(''my detailed description'')
except MyException as my:
print my # outputs ''my detailed description''
Puede utilizar str(my)
o (menos elegante) my.args[0]
para acceder al mensaje personalizado.
Fondo
En las versiones más nuevas de Python (desde 2.6) se supone que debemos heredar nuestras clases de excepción personalizadas de Exception que (a partir de Python 2.5 ) hereda de BaseException. El fondo se describe en detalle en PEP 352 .
class BaseException(object):
"""Superclass representing the base of the exception hierarchy.
Provides an ''args'' attribute that contains all arguments passed
to the constructor. Suggested practice, though, is that only a
single string argument be passed to the constructor."""
__str__
y __repr__
ya están implementados de manera significativa, especialmente para el caso de una sola arg (que puede usarse como mensaje).
No necesita repetir la implementación de __str__
o __init__
o crear _get_message
como lo sugirieron otros.
Continuando con la respuesta de geekQ , el reemplazo del código preferido depende de lo que necesite hacer:
### Problem
class MyException(Exception):
"""My documentation"""
try:
raise MyException(''my detailed description'')
except MyException as my:
### Solution 1, fails in Python 2.x if MyException contains 🔥
# with UnicodeEncodeError: ''ascii'' codec can''t encode characters in position 24-25: ordinal not in range(128)
print(my) # outputs ''my detailed description''
### Solution 2
# Works in Python 2.x if exception only has ASCII characters,
# should always work in Python 3.x
str(my)
### Solution 3
# Required in Python 2.x if you need to handle non-ASCII characters,
# such as δσφφδσ (as pointed out by jjc) or emoji 🔥 💕 🎁 💯 🌹
# but does not work in Python 3.x
unicode(my)
En ocasiones, las excepciones tienen más de un argumento, por lo que my.args[0]
no garantiza que proporcione toda la información relevante.
Por ejemplo:
# Python 2.7
try:
u''/u12345''.encode(''utf-8'').encode(''utf-8'')
except UnicodeDecodeError as e:
print e.args[0]
print e.args
print str(e)
Imprime como salida:
ascii
(''ascii'', ''/xe1/x88/xb45'', 0, 1, ''ordinal not in range(128)'')
''ascii'' codec can''t decode byte 0xe1 in position 0: ordinal not in range(128)
Sin embargo, es una compensación sensible al contexto, porque, por ejemplo:
# Python 2.7
>>> str(SyntaxError())
''None''
# ''None'' compares True which might not be expected
El consejo de usar str (myexception) lleva a problemas unicode en python 2.7, por ejemplo:
str(Exception(u''δσφφδσ''))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeEncodeError: ''ascii'' codec can''t encode characters in position 0-5: ordinal not in range(128)
:(
unicode(Exception(u''δσφφδσ''))
funciona como se espera, y se prefiere en casos donde parte del contenido de la cadena de error incluye la entrada del usuario
La publicación de pzrq dice usar:
str(e)
Esto era exactamente lo que necesitaba.
(Si se encuentra en un entorno Unicode, parece que:
unicode(e)
funcionará, y parece funcionar bien en un entorno no unicode)
Pzrq dijo muchas otras cosas buenas, pero casi me perdí su respuesta debido a todas las cosas buenas. Como no tengo 50 puntos, no puedo comentar su respuesta para tratar de llamar la atención sobre la solución simple que funciona, y dado que no tengo 15, no puedo votar esa respuesta, pero puedo publicarla (se siente hacia atrás, pero oh bien) - así que aquí estoy publicando - probablemente pierda puntos por eso ...
Como mi objetivo es llamar la atención sobre la respuesta de pzrq, por favor no la esmaltes y la omitas en todo lo que sigue. las primeras líneas de esta publicación son las más importantes.
Mi historia:
El problema por el que vine aquí fue si quieres atrapar una excepción de una clase sobre la que no tienes control, ¿entonces qué? ¡Ciertamente no voy a subclasificar todas las clases posibles que usa mi código para intentar sacar un mensaje de todas las posibles excepciones!
Estaba usando:
except Exception as e:
print ''%s (%s)'' % (e.message,type(e))
que, como todos sabemos ahora, da la advertencia de la que OP me preguntó (que me trajo aquí), y esto, que pzrq da como una forma de hacerlo:
except Exception as e:
print ''%s (%s)'' % (str(e),type(e))
No.
No estoy en un entorno Unicode, pero la respuesta de jjc me hizo preguntarme, así que tuve que intentarlo. En este contexto, esto se convierte en:
except Exception as e:
print ''%s (%s)'' % (unicode(e),type(e))
que, para mi sorpresa, funcionó exactamente como str (e) - entonces ahora eso es lo que estoy usando.
No sé si ''str (e) / unicode (e)'' es la ''forma aprobada de Python'', y probablemente descubro por qué eso no es bueno cuando llegue a 3.0, pero uno espera que la capacidad de manejar una excepción inesperada (*) sin morir y aún obtener algo de información que nunca desaparecerá ...
(*) Hmm. "excepción inesperada" - ¡Creo que tartamudeé!
Por lo que puedo decir, simplemente usar un nombre diferente para el atributo de mensaje evita el conflicto con la clase base y, por lo tanto, detiene la advertencia de desactivación:
class MyException(Exception):
def __init__(self, message):
self.msg = message
def __str__(self):
return repr(self.msg)
Parece un truco para mí.
Tal vez alguien pueda explicar por qué se emite la advertencia incluso cuando la subclase define explícitamente un atributo de mensaje. Si la clase base ya no tiene este atributo, no debería haber un problema.
Sí, está en desuso en Python 2.6 porque se va en Python 3.0
La clase BaseException ya no proporciona una forma de almacenar el mensaje de error. Tendrás que implementarlo tú mismo. Puede hacer esto con una subclase que usa una propiedad para almacenar el mensaje.
class MyException(Exception):
def _get_message(self):
return self._message
def _set_message(self, message):
self._message = message
message = property(_get_message, _set_message)
Espero que esto ayude
class MyException(Exception):
def __str__(self):
return repr(self.args[0])
e = MyException(''asdf'')
print e
Esta es tu clase en el estilo Python2.6. La nueva excepción toma una cantidad arbitraria de argumentos.