¿Cómo deshacerse de los mensajes de advertencia específicos en python mientras se mantienen todas las demás advertencias como de costumbre?

4 minutos de lectura

avatar de usuario
Alma perdida

Estoy haciendo algunas matemáticas simples recesivamente en un script de python y recibo la siguiente advertencia:

“Advertencia: dividir por cero encontrado en dividir”.

Para proporcionar algo de contexto, estoy tomando dos valores y tratando de encontrar la diferencia porcentual en el valor (a - b) / a y si está por encima de cierto rango, entonces procéselo, pero a veces el valor de a o b es cero

Quiero deshacerme de esta advertencia específica (en una línea específica), pero toda la información que he encontrado hasta ahora parece mostrarme cómo detener todas las advertencias (que no quiero).

Cuando solía escribir scripts de shell, podía hacer algo como esto

code...
more code 2 > error.txt
even more code  

En ese ejemplo, obtendría las advertencias para el comando ‘código’ e ‘aún más código’ pero no para la segunda línea.

es posible?

  • ¿Por qué no verificar si a o b == 0 y no hacer el cálculo?

    – AlG

    3 de febrero de 2012 a las 20:07

  • Esa no es una advertencia habitual de Python, ¿puede mostrar el código que está ejecutando?

    –Ned Batchelder

    3 de febrero de 2012 a las 20:07

  • eso debería ser una excepción, no una advertencia, ¿no? no puedes atrapar el ZeroDivisionError?

    – mpen

    3 de febrero de 2012 a las 20:08

  • Pensé en eso, pero el resultado (que es cero) es exactamente lo que ya quiero. Creo que en el peor de los casos, solo haré eso, pero tenía curiosidad por saber si había una forma de suprimir mensajes específicos en python.

    – Alma perdida

    3 de febrero de 2012 a las 20:08

  • Es una advertencia, estoy usando numpy/scipy y creo que esos módulos están generando el error cuando estoy dividiendo

    – Alma perdida

    3 de febrero de 2012 a las 20:09

Si Scipy está usando el warnings módulo, entonces puede suprimir advertencias específicas. Pruebe esto al comienzo de su programa:

import warnings
warnings.filterwarnings("ignore", message="divide by zero encountered in divide")

Si desea que esto se aplique solo a una sección de código, use el administrador de contexto de advertencias:

import warnings
with warnings.catch_warnings():
    warnings.filterwarnings("ignore", message="divide by zero encountered in divide")
    # .. your divide-by-zero code ..

  • ¿Cómo? Vi que puedo desactivar todas las advertencias, pero ¿es posible apuntar a una línea de código específica?

    – Alma perdida

    3 de febrero de 2012 a las 20:11

  • ¡Oh, acabo de ver tu actualización!… Gracias, eso era lo que estaba buscando. Una pregunta más, ¿hay una forma específica de encontrar el mensaje de advertencia o es simplemente lo que aparece en la pantalla? Si recibo “Advertencia: su código apesta, ¡alma perdida!”, Entonces puedo agregar eso a la variable de mensaje anterior y ¿funcionaría?

    – Alma perdida

    3 de febrero de 2012 a las 20:13

  • Buena respuesta. En realidad, me tomó una sorprendente cantidad de búsquedas en Google encontrar esta explicación ultra simple de cómo ignorar las advertencias. @Lostsoul puede usar message=’mensaje de coincidencia de expresión regular’ para detectar advertencias por mensaje, y también hay argumentos lineno= y module= para detectar por número de línea y nombre de módulo.

    – cxrodgers

    7 febrero 2013 a las 23:02

avatar de usuario
Licuadora

Evitaría la división por cero en primer lugar:

if a == 0:
    # Break out early

# Otherwise the ratio makes sense

Si desea aplastar esa advertencia numpy en particular en una sola línea, numpy proporciona lejos:

with numpy.errstate(divide="ignore"):
    # The problematic line

  • Gracias Blender, ese fue mi primer pensamiento, pero tenía curiosidad por saber si había una manera de suprimir una advertencia específica. Si no hay manera (o es muy complicado, definitivamente seguiré tu enfoque)

    – Alma perdida

    03/02/2012 a las 20:10

  • si realmente lo está haciendo (a-b)/a entonces verificar si a o b es cero es una tontería. solo necesita marcar un!

    – mpen

    3 de febrero de 2012 a las 20:12

  • @Mark: Eso es lo que pensé originalmente, pero cuando el OP dijo pero a veces el valor de a o b es ceroeso me confundió.

    – Licuadora

    3 de febrero de 2012 a las 20:13

  • @Blender: Es como esas preguntas que recibió en la escuela donde a veces le dieron información adicional (b puede ser 0) que no es realmente relevante para resolver el problema: D

    – mpen

    3 de febrero de 2012 a las 23:42

La respuesta de Blenders se ajusta perfectamente al problema. Tal vez alguien esté interesado en otro enfoque general para detectar advertencias específicas con expresiones regulares o el número de línea:

suprima una advertencia causada por una línea específica, aquí la línea 113:

import warnings
warnings.simplefilter('ignore',lineno=113)

Este enfoque tiene la desventaja de que cada vez que cambia algo en el código necesita reajustar el lineno. La otra opción es captar una advertencia usando expresiones regulares. El siguiente código devolverá

import warnings
warnings.filterwarnings('ignore', message=".*show", )
warnings.warn('Do not do this!')
warnings.warn('Do not show this message')
>>> UserWarning: Do not do this!
        warnings.warn('Do not do this!')

El punto antes del símbolo * es necesario ya que de lo contrario se devuelve un error

error: nothing to repeat

que se comenta en este hilo

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad