ปกติโปรแกรมไพธอนเวลารันอยู่แล้วเจอข้อผิดพลาดโปรแกรมก็จะหยุดทำงานแล้วก็ชี้แจงข้อผิดพลาดออกมาให้เห็นทันที
ในบทเรียนภาษาไพธอนเนื้อหาหลักได้กล่าวถึงการจัดการข้อยกเว้นโดยใช้ try และ except ไปแล้ว
https://phyblas.hinaboshi.com/tsuchinoko25 วิธีนี้ช่วยให้โปรแกรมสามารถดำเนินต่อไปได้อย่างราบรื่น แม้ว่าจะเจอข้อผิดพลาดที่ไม่คาดคิดก็ตาม
อย่างไรก็ตาม วิธีนี้มีปัญหาอยู่อย่างก็คือ หากต้องการหยุดโปรแกรมขึ้นมากะทันหันจะทำได้ยากขึ้น
เพราะปกติเวลาที่เราต้องการหยุดโปรแกรมกลางคันอาจทำได้โดยกด ctrl+c พอทำแบบนี้ไปแล้วจะเป็นการส่ง KeyboardInterrupt Exception เข้าไปที่โปรแกรม ทำให้โปรแกรมเกิดข้อผิดพลาดแล้วก็หยุดทำงานลง
แต่ปัญหาคือ KeyboardInterrupt Exception ก็เป็นข้อยกเว้นชนิดหนึ่ง เมื่อเจอกับ try ก็จะโดนยกเลิกข้อผิดพลาด และไม่มีการหยุดทำงานโปรแกรมจริงๆ
ดังนั้นวิธีการแก้ก็คือให้ตั้งเงื่อนไขแยกไว้ว่าหากเจอ KeyboardInterrupt Exception ให้ทำการออกจากโปรแกรมจริงๆ
ยกตัวอย่างง่ายๆ เช่นลองเขียนโปรแกรมที่มีการวนซ้ำให้สุ่มตัวเลข ๒ ตัว ตั้งแต่ -5 ถึง 5 มาหารแล้วแสดงผลออกมา โดยเว้นทีละวินาที
import random,time
for i in range(100):
a = random.randint(-5,5)
b = random.randint(-5,5)
print('%d หาร %d ได้ %.3f'%(a,b,a/b))
time.sleep(1)
จะพบว่าเมื่อรันไปสักพักพอค่า b ถูกสุ่มออกมาได้ 0 ก็จะขึ้นว่า
----> 6 print('%d หาร %d ได้ %.3f'%(a,b,a/b))
7 time.sleep(1)
ZeroDivisionError: division by zero
ดังนั้นเพื่อไม่ให้เกิด error แบบนี้อาจเขียนแก้ด้วย try except เป็นแบบนี้
for i in range(100):
a = random.randint(-5,5)
b = random.randint(-5,5)
try:
print('%d หาร %d ได้ %.3f'%(a,b,a/b))
time.sleep(1)
except:
print('%d หาร %d ได้อนันต์'%(a,b))
พอทำแบบนี้เราก็คงจะสามารถพอใจกับผลลัพธ์ที่ได้ แต่หากต้องการหยุดกลางคันจะทำไม่ได้ ลองกด ctrl+c เท่าไหร่โปรแกรมก็จะไม่หยุดสักที ได้แต่รอให้โปรแกรมรันไปจนจบเอง
ดังนั้นอาจแก้ด้วยการเพิ่มเงื่อนไขว่าหากเป็น KeyboardInterrupt ก็ให้หยุดไปเลยตามปกติ แบบนี้
for i in range(100):
a = random.randint(-5,5)
b = random.randint(-5,5)
try:
print('%d หาร %d ได้ %.3f'%(a,b,a/b))
time.sleep(1)
except KeyboardInterrupt:
raise
except:
print('%d หาร %d ได้อนันต์'%(a,b))
แค่เติมส่วนของ except KeyboardInterrupt เข้าไปเท่านั้น เพียงแค่นี้เมื่อกด ctrl+c ก็จะสามารถหยุดได้แล้ว ส่วนกรณีเจอข้อผิดพลาดแบบอื่นโปรแกรมก็จะยังคงดำเนินต่อไป
พอเขียนแบบนี้เท่านี้ก็ไม่ต้องกังวลแล้ว
หนึ่งในตัวอย่างการใช้งานจริง เช่น เวลาเขียนโปรแกรมเพื่อล้วงข้อมูลจากเว็บ >>
https://phyblas.hinaboshi.com/20180329 ในนั้นจะเห็นว่ามีการใช้ except KeyboardInterrupt ในส่วนที่ทำการโหลดภาพ
อีกอย่างคือควรจะเขียนคำสั่งสำหรับจัดการอะไรบางอย่างในที่อาจเหลือค้างในกรณีที่หยุดกลางคันด้วย เช่นกรณีที่ทำการโหลดไฟล์อยู่ หากหยุดกลางคันก็ให้ลบไฟล์ทิ้ง ไม่งั้นไฟล์ที่โหลดอยู่กลางคันก็จะเหลือเป็นขยะค้างอยู่ในเครื่อง ต้องมาทำการลบออกเองภายหลัง