Recibo una advertencia de que BaseException.message está en desuso en Python 2.6 cuando uso 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é tiene de malo esto? ¿Qué debo cambiar para deshacerme de la advertencia de desaprobación?
python
exception
deprecated
Desolat
fuente
fuente
Respuestas:
Solución: casi no se necesita codificación
Simplemente herede su clase de excepción
Exception
y pase el mensaje como primer parámetro al constructorEjemplo:
Puede usar
str(my)
o (menos elegante)my.args[0]
para acceder al mensaje personalizado.Antecedentes
En las versiones más recientes de Python (de 2.6) se supone que heredemos 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 .
__str__
y__repr__
ya están implementados de manera significativa, especialmente para el caso de un solo argumento (que puede usarse como mensaje).No necesita repetir
__str__
o__init__
implementar o crear_get_message
según lo sugerido por otros.fuente
str
interrupciones si la excepción se construyó con un argumento unicode:str(MyException(u'\xe5'))
planteaUnicodeEncodeError
. El uso enunicode
lugar destr
no es infalible porqueunicode(MyException('\xe5'))
aumenta UnicodeDecodeError. ¿Significa esto que si no sé de antemano si el argumento esstr
ounicode
tengo que usarlo.args[0]
donde lo usé anteriormente.message
?.message
en nuestro proyecto con.args[0]
, y eso no nos ha causado ningún problema.Sí, está en desuso en Python 2.6 porque desaparecerá en Python 3.0
La clase BaseException ya no proporciona una forma de almacenar mensajes de error. Tendrás que implementarlo tú mismo. Puede hacer esto con una subclase que usa una propiedad para almacenar el mensaje.
Espero que esto ayude
fuente
@property
sintaxis cuando realmente necesite encapsulación.@property
para deshabilitar la advertencia de desaprobación.Esta es tu clase en estilo Python2.6. La nueva excepción toma un número arbitrario de argumentos.
fuente
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 en Python 2.6 y 2.7, si tiene las advertencias activadas (a través del
-W
indicador , laPYTHONWARNINGS
variable de entorno o el módulo de advertencias ):Dejar de usar
.message
Prefiero
repr(error)
, que devuelve una cadena que contiene el nombre del tipo de error, la repr del mensaje, si hay una, y la repr de los argumentos restantes.Eliminando la advertencia mientras sigue usando
.message
Y la forma de deshacerse de él
DeprecationWarning
es subclasificar una excepción integrada como pretendían los diseñadores de Python:obteniendo solo el
.message
atributo sinerror.message
Si sabe que hubo un argumento, un mensaje, para la Excepción y eso es lo que desea, es preferible evitar el atributo del mensaje y simplemente eliminar
str
el error. Digamos para una subclaseException
:Y uso:
Ver también esta respuesta:
¿Forma correcta de declarar excepciones personalizadas en Python moderno?
fuente
Por lo que puedo decir, el simple uso de un nombre diferente para el atributo del mensaje evita el conflicto con la clase base y, por lo tanto, detiene la advertencia de desaprobación:
Me parece un truco.
Quizás alguien pueda explicar por qué se emite la advertencia incluso cuando la subclase define un atributo de mensaje explícitamente. Si la clase base ya no tiene este atributo, no debería haber ningún problema.
fuente
Continuando con la respuesta de geekQ , el reemplazo de código preferido depende de lo que debe hacer:
A veces las excepciones tienen más de un argumento, así que
my.args[0]
lo que no se garantiza que proporcione toda la información relevante.Por ejemplo:
Imprime como salida:
Sin embargo, es una compensación sensible al contexto, porque, por ejemplo:
fuente
str(my)
lugar demy.message
.El consejo de usar str (myexception) conduce a problemas Unicode en Python 2.7, por ejemplo:
:(
funciona como se esperaba y se prefiere en los casos en que parte del contenido de la cadena de error incluye la entrada del usuario
fuente
La publicación de pzrq dice usar:
Esto era exactamente lo que necesitaba.
(Si se encuentra en un entorno Unicode, parece que:
funcionará, y parece funcionar bien en un entorno no Unicode)
Pzrq dijo muchas otras cosas buenas, pero casi me pierdo su respuesta debido a todas las cosas buenas. Como no tengo 50 puntos, no puedo comentar su respuesta para intentar llamar la atención sobre la solución simple que funciona, y como no tengo 15, no puedo votar esa respuesta, pero puedo publicar (se siente al revés, pero oh bueno), así que aquí estoy publicando, probablemente pierda puntos por eso ...
Dado que mi punto es llamar la atención sobre la respuesta de pzrq, por favor, no te deslumbres y te lo pierdas 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 en un intento de poder obtener un mensaje de todas las posibles excepciones!
Estaba usando:
que, como todos sabemos, da la advertencia sobre la que OP preguntó (que me trajo aquí), y esto, que pzrq da como una forma de hacerlo:
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:
que, para mi sorpresa, funcionó exactamente como str (e), así que ahora eso es lo que estoy usando.
No sé si 'str (e) / unicode (e)' es la 'forma aprobada de Python', y probablemente descubriré por qué eso no es bueno cuando llegue a 3.0, pero uno espera que la capacidad de manejar un excepción inesperada (*) sin morir y aún así obtener información de ella nunca desaparecerá ...
(*) Hmm. "excepción inesperada" - ¡Creo que simplemente tartamudeé!
fuente