Genera avviso in Python senza interrompere il programma


189

Sto cercando di generare un avviso in Python senza interrompere il programma / interrompere / interrompere il programma.

Uso la seguente semplice funzione per verificare se l'utente gli ha passato un numero diverso da zero. In tal caso, il programma dovrebbe avvisarli, ma continuare normalmente. Dovrebbe funzionare come il codice qui sotto, ma dovrebbe utilizzare la classe Warning(), Error()o Exception()invece di stampare l'avviso manualmente.

def is_zero(i):
   if i != 0:
     print "OK"
   else:
     print "WARNING: the input is 0!"
   return i

Se uso il codice qui sotto e passo 0 alla funzione, il programma si arresta in modo anomalo e il valore non viene mai restituito. Invece, voglio che il programma continui normalmente e informo semplicemente l'utente che ha passato 0 alla funzione.

def is_zero(i):
   if i != 0:
     print "OK"
   else:
     raise Warning("the input is 0!")
   return i

Voglio essere in grado di provare che è stato lanciato un avviso testandolo da unittest. Se stampo semplicemente il messaggio, non riesco a provarlo con assertRaises in unittest.


Come vuoi avvisare esattamente l'utente? tramite e-mail o SMS? perché può essere collegato ma è necessario essere specifici.
aaronasterling

2
Perché non ti limiti printal messaggio?
sje397,

1
@ sje397 Il punto è che voglio essere in grado di provare che è stato lanciato un avviso testandolo da unittest. Se stampo semplicemente il messaggio, non riesco a farlo con assertRaises in unittest.
Tomas Novotny,

Risposte:


157

Non dovresti raiseavvertire, dovresti usare il warningsmodulo. Alzandolo stai generando un errore, piuttosto che un avvertimento.


1
Grazie mille. E come posso quindi verificare che l'avviso sia stato lanciato utilizzando unittest? Non posso più usare assertRaises ().
Tomas Novotny,

@Tomas Novotny puoi catturare stdout e stderr, quindi controllare che le stringhe emesse dal tuo avviso siano presenti all'interno.
wheaties

15
@Tomas: Non ho mai sentito parlare del desiderio di provare per un avviso, ma è disponibile un warnings.catch_warningsgestore di contesto che ti permetterà di farlo.
SilentGhost,

290
import warnings
warnings.warn("Warning...........Message")

Consulta la documentazione di Python: qui


6
E warnings.warn("blabla", DeprecationWarning)per aver aggiunto una classe al tipo di avviso emesso
Shadi,

52

Per impostazione predefinita, a differenza di un'eccezione, un avviso non si interrompe.

Successivamente import warnings, è possibile specificare una classe Avvertenze quando si genera un avviso. Se uno non è specificato, è letteralmente UserWarningper impostazione predefinita.

>>> warnings.warn('This is a default warning.')
<string>:1: UserWarning: This is a default warning.

Per utilizzare semplicemente una classe preesistente, ad esempio DeprecationWarning:

>>> warnings.warn('This is a particular warning.', DeprecationWarning)
<string>:1: DeprecationWarning: This is a particular warning.

La creazione di una classe di avviso personalizzata è simile alla creazione di una classe di eccezione personalizzata:

>>> class MyCustomWarning(UserWarning):
...     pass
... 
... warnings.warn('This is my custom warning.', MyCustomWarning)

<string>:1: MyCustomWarning: This is my custom warning.

Per i test, considerare assertWarnso assertWarnsRegex.


In alternativa, in particolare per le applicazioni autonome, considerare il loggingmodulo. Può registrare messaggi con un livello di debug , informazioni , avvertenze , errori , ecc. I messaggi di registro con un livello di avviso o superiore vengono stampati per impostazione predefinita su stderr.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.