แจ้งเตือนใน Python โดยไม่รบกวนโปรแกรม


189

ฉันพยายามเพิ่มคำเตือนใน Python โดยไม่ทำให้โปรแกรมขัดข้อง / หยุด / ขัดจังหวะ

ฉันใช้ฟังก์ชันง่าย ๆ ต่อไปนี้เพื่อตรวจสอบว่าผู้ใช้ผ่านหมายเลขที่ไม่ใช่ศูนย์หรือไม่ ถ้าเป็นเช่นนั้นโปรแกรมควรเตือนพวกเขา แต่ดำเนินการต่อตามปกติ มันควรจะทำงานเช่นโค้ดด้านล่าง แต่ควรใช้คลาสWarning(), Error()หรือException()แทนการพิมพ์คำเตือนด้วยตนเอง

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

ถ้าฉันใช้รหัสด้านล่างและส่งผ่าน 0 ไปยังฟังก์ชันโปรแกรมขัดข้องและไม่มีการคืนค่า แต่ฉันต้องการให้โปรแกรมทำงานต่อตามปกติและเพียงแจ้งผู้ใช้ว่าเขาผ่าน 0 ไปยังฟังก์ชัน

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

ฉันต้องการที่จะทดสอบว่าคำเตือนถูกส่งไปทดสอบโดยไม่แสดงความคิดเห็น หากฉันพิมพ์ข้อความออกมาฉันไม่สามารถทดสอบด้วย assertRaises แบบไม่ตอบสนองได้


คุณต้องการแจ้งผู้ใช้อย่างไร ผ่านอีเมลหรือ SMS? สาเหตุที่สามารถติดยาเสพติดได้ แต่คุณต้องเจาะจง
aaronasterling

2
ทำไมคุณไม่เพียงแค่printข้อความ
sje397

1
@ sje397 ประเด็นก็คือว่าฉันต้องการที่จะทดสอบว่าคำเตือนถูกส่งออกไปโดยไม่ตั้งใจ หากฉันพิมพ์ข้อความออกมาฉันไม่สามารถทำได้โดยใช้ assertRaises โดยไม่พูดถึง
Tomas Novotny

คำตอบ:


157

คุณไม่ควรraiseเตือนคุณควรใช้warningsโมดูล โดยการเพิ่มมันคุณกำลังสร้างข้อผิดพลาดมากกว่าการเตือน


1
ขอบคุณมาก. แล้วฉันจะทดสอบได้อย่างไรว่าคำเตือนนั้นถูกส่งออกไปโดยไม่ใช้ความระมัดระวัง? ฉันไม่สามารถใช้ assertRaises () ได้อีกต่อไป
Tomas Novotny

@Tomas Novotny คุณสามารถจับ stdout และ stderr จากนั้นตรวจสอบว่าสตริงที่ออกโดยคำเตือนของคุณอยู่ภายใน
ข้าวสาลี

15
@ โทมัส: ฉันไม่เคยได้ยินความปรารถนาที่จะทดสอบคำเตือน แต่มีwarnings.catch_warningsผู้จัดการบริบทที่ให้คุณทำสิ่งนี้ได้
SilentGhost

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

ดูเอกสารหลาม: ที่นี่


6
และwarnings.warn("blabla", DeprecationWarning)สำหรับการเพิ่มชั้นเรียนให้กับชนิดของการเตือนที่ออก
shadi

52

ตามค่าเริ่มต้นซึ่งแตกต่างจากข้อยกเว้นคำเตือนจะไม่ขัดจังหวะ

หลังจากimport warningsนั้นเป็นไปได้ที่จะระบุคลาสคำเตือนเมื่อสร้างคำเตือน หากไม่มีการระบุไว้จะมีการระบุUserWarningค่าเริ่มต้นตามตัวอักษร

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

หากต้องการใช้คลาสที่มีอยู่ก่อนหน้าแทนเช่นDeprecationWarning:

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

การสร้างคลาสคำเตือนที่กำหนดเองจะคล้ายกับการสร้างคลาสยกเว้นที่กำหนดเอง:

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

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

สำหรับการทดสอบพิจารณาหรือassertWarnsassertWarnsRegex


เป็นทางเลือกโดยเฉพาะอย่างยิ่งสำหรับแอปพลิเคชันแบบสแตนด์อโลนให้พิจารณาloggingโมดูล มันสามารถบันทึกข้อความที่มีระดับของการแก้ปัญหา , ข้อมูล , เตือน , ข้อผิดพลาดฯลฯ ข้อความเข้าสู่ระบบที่มีระดับของการเตือนหรือสูงกว่าโดยเริ่มต้นพิมพ์ไป stderr

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.