2010-02-02 8 views
22

Sto emettendo molti avvisi in un validatore e vorrei eliminare tutto in stdout tranne il messaggio fornito a warnings.warn().Python: stampa solo il messaggio sugli avvisi

Vale a dire, ora vedo questo:

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

mi piacerebbe vedere questo:

My looong warning message 

Edit 2: Overriding warnings.showwarning() si è rivelato il lavoro:

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

risposta

13

Monkeypatch warnings.showwarning() con la propria funzione personalizzata ionico.

+5

Hai letto il link? E cito: "Puoi sostituire questa funzione con un'implementazione alternativa assegnando a warnings.showwarning.". Il manuale * stesso * consiglia di monkeypatch il modulo. –

+0

non ti preoccupare, è perfettamente normale la procedura python, non è affatto drastica. –

12

C'è sempre 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

su Python 3.6 Ottengo TypeError: custom_formatwarning() ha ottenuto un argomento di parole chiave inaspettate 'line'. Così ho cambiato la firma della funzione in: 'def custom_formatwarning (messaggio, categoria, nomefile, lineno, riga = '')' –

+0

Ho avuto lo "stesso argomento" keyword "in Python 3.6, ma ho appena cambiato la firma per 'def custom_formatwarning (msg, * a, ** b):' così cattura anche le parole chiave args. – SuperGeo

6

Utilizzare la logging module invece di warnings.

+0

Questo è quello con cui mi sono ritrovato nella maggior parte delle situazioni in cui inizialmente avevo provato ad usare "warnings". Se stai lottando con 'warnings', dovresti considerare questa opzione. Sul serio. – tripleee

6

Ecco cosa sto facendo per omettere solo la riga del codice sorgente. Questo è in linea di massima come suggerito dalla documentazione, ma è stato un po 'difficile capire cosa esattamente cambiare. (In particolare, ho cercato in vari modi per mantenere la linea fonte di showwarnings ma non sono riuscito a farlo funzionare nel modo che volevo.)

# 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='') 

Solo di passaggio line=None causerebbe Python da usare filename e lineno a calcolare un valore per line automaticamente, ma il passaggio di una stringa vuota invece lo risolve.

+0

So che è super vecchio, ma ho fatto una cosa simile e anche questo ha funzionato. Tuttavia, se lo faccio all'interno di una funzione, il comportamento di avviso cambia sull'ambito globale. Ogni avviso arriva dopo aver chiamato quella funzione adotta il comportamento modificato. Conosci un modo per limitarne l'effetto? – percusse

+0

Hmm, l'ho sempre usato solo nel contesto globale. Come soluzione alternativa, è possibile definire una variabile globale che viene utilizzata all'interno di 'lambda' per decidere se il valore' line' è sovrascritto o meno. (A quel punto, forse usi una funzione con nome piuttosto che una 'lambda'?) – tripleee

+0

Sfortunatamente non importava dove facessi queste cose. Ho anche provato il salvataggio e il ripristino originali della defeinition, ma non ancora disponibile. – percusse