Naikkan peringatan dengan Python tanpa mengganggu program

189

Saya mencoba untuk meningkatkan Peringatan dengan Python tanpa membuat program crash / stop / interrupt.

Saya menggunakan fungsi sederhana berikut untuk memeriksa apakah pengguna memberikan angka bukan nol. Jika demikian, program harus memperingatkan mereka, tetapi lanjutkan seperti biasa. Seharusnya berfungsi seperti kode di bawah ini, tetapi harus menggunakan kelas Warning(), Error()atau Exception()bukannya mencetak peringatan secara manual.

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

Jika saya menggunakan kode di bawah ini dan meneruskan 0 ke fungsi, program macet dan nilainya tidak pernah dikembalikan. Sebagai gantinya, saya ingin program untuk melanjutkan secara normal dan hanya memberitahu pengguna bahwa ia melewati 0 ke fungsi.

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

Saya ingin dapat menguji bahwa suatu peringatan telah dilemparkan mengujinya dengan cara yang belum terbukti. Jika saya hanya mencetak pesan, saya tidak dapat mengujinya dengan assertRaises di unittest.

Tomas Novotny
sumber
Bagaimana tepatnya Anda ingin memberi tahu pengguna? melalui email atau SMS? Penyebab yang dapat dihubungkan tetapi Anda harus spesifik.
aaronasterling
2
Kenapa kamu tidak printpesan saja?
sje397
1
@ sje397 Intinya adalah bahwa saya ingin dapat menguji bahwa peringatan telah dilemparkan dengan mengujinya secara unittest. Jika saya hanya mencetak pesan, saya tidak dapat melakukannya dengan AssertRaises di unittest.
Tomas Novotny

Jawaban:

157

Anda seharusnya tidak memberi raiseperingatan, Anda harus menggunakan warningsmodul. Dengan menaikkannya Anda menghasilkan kesalahan, bukan peringatan.

SilentGhost
sumber
1
Terima kasih banyak. Dan bagaimana cara saya menguji bahwa Peringatan telah dilempar menggunakan unittest? Saya tidak bisa menggunakan assertRaises () lagi.
Tomas Novotny
@ Thomas Novotny Anda dapat menangkap stdout dan stderr, lalu periksa apakah string yang dikeluarkan oleh peringatan Anda ada di dalam.
wheaties
15
@ Thomas: Saya tidak pernah mendengar keinginan untuk menguji peringatan, tetapi ada warnings.catch_warningspengelola konteks yang memungkinkan Anda melakukan ini.
SilentGhost
290
import warnings
warnings.warn("Warning...........Message")

Lihat dokumentasi python: di sini

ahli nujum
sumber
6
Dan warnings.warn("blabla", DeprecationWarning)untuk menambahkan kelas untuk jenis peringatan yang dikeluarkan
shadi
52

Secara default, tidak seperti pengecualian, peringatan tidak mengganggu.

Setelah import warningsitu, dimungkinkan untuk menentukan kelas Peringatan saat membuat peringatan. Jika tidak ditentukan, secara harfiah adalah UserWarningdefault.

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

Untuk hanya menggunakan kelas yang sudah ada sebagai gantinya, misalnya DeprecationWarning:

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

Membuat kelas peringatan khusus mirip dengan membuat kelas pengecualian khusus:

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

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

Untuk pengujian, pertimbangkan assertWarnsatau assertWarnsRegex.


Sebagai alternatif, terutama untuk aplikasi mandiri, pertimbangkan loggingmodul ini. Itu dapat mencatat pesan yang memiliki tingkat debug , info , peringatan , kesalahan , dll. Pesan log yang memiliki tingkat peringatan atau lebih tinggi secara default dicetak ke stderr.

Acumenus
sumber