2010-02-02 13 views
22

Estoy emitiendo muchas advertencias en un validador, y me gustaría suprimir todo en stdout excepto el mensaje que se proporciona a warnings.warn().Python: Imprima solo el mensaje en las advertencias

Es decir, ahora veo esto:

./file.py:123: UserWarning: My looong warning message 
some Python code 

Me gustaría ver esto:

My looong warning message 

Edición 2: Anulación warnings.showwarning() resultó trabajo:

def _warning(
    message, 
    category = UserWarning, 
    filename = '', 
    lineno = -1): 
    print(message) 
... 
warnings.showwarning = _warning 
warnings.warn('foo') 

Respuesta

13

Monkeypatch warnings.showwarning() con su propia función personalizada ion.

+5

¿Has leído el enlace? Y cito: "Puede reemplazar esta función con una implementación alternativa asignando warnings.showwarning". El manual * en sí * recomienda que monopatche el módulo. –

+0

no se preocupe, es un procedimiento de pitón perfectamente normal, no drástico en absoluto. –

12

Siempre hay monkeypatching:

import warnings 

def custom_formatwarning(msg, *a): 
    # ignore everything except the message 
    return str(msg) + '\n' 

warnings.formatwarning = custom_formatwarning 
warnings.warn("achtung") 
+0

en Python 3.6 obtengo TypeError: custom_formatwarning() obtuvo un argumento de palabra clave inesperado 'línea'. Así que cambié la firma de la función a: 'def custom_formatwarning (message, category, filename, lineno, line = '')' –

+0

Tuve la misma 'línea' de argumento de palabras clave "en Python 3.6, pero acabo de cambiar la firma para 'def custom_formatwarning (msg, * a, ** b): 'por lo que también captura palabras clave args. – SuperGeo

6

Utilice la logging module en lugar de warnings.

+0

Esto es con lo que he terminado en la gran mayoría de las situaciones en las que originalmente intenté usar 'advertencias'. Si estás luchando con 'advertencias', deberías considerar esta opción. Seriamente. – tripleee

6

Esto es lo que estoy haciendo para omitir solo la línea del código fuente. Esto es, en general, como lo sugiere la documentación, pero fue un poco difícil determinar exactamente qué cambiar. (En particular, he intentado en varias formas de mantener la línea de fuentes de showwarnings pero no pude conseguir que funcione de la manera que quería.)

# Force warnings.warn() to omit the source code line in the message 
formatwarning_orig = warnings.formatwarning 
warnings.formatwarning = lambda message, category, filename, lineno, line=None: \ 
    formatwarning_orig(message, category, filename, lineno, line='') 

De paso line=None causaría Python para usar filename y lineno a averiguar un valor para line automágicamente, pero pasar una cadena vacía en su lugar corrige eso.

+0

Sé que esto es muy viejo, pero he hecho algo similar y eso también funcionó. Sin embargo, si hago esto dentro de una función, el comportamiento de advertencia cambia en el alcance global. Cada advertencia viene después de llamar a que la función adopta el comportamiento modificado. ¿Conoces una forma de limitar su efecto? – percusse

+0

Hmm, solo he usado esto en un contexto global. Como una solución anormal, podría definir una variable global que se utiliza dentro de la 'lambda' para decidir si el valor de la 'línea' se anula o no. (En ese momento, ¿quizás use una función nombrada en lugar de una 'lambda'?) – tripleee

+0

Desafortunadamente no importaba dónde hice estas cosas. También probé la defeinición original guardando y restaurando pero aún no sirvió para nada. – percusse

Cuestiones relacionadas