Python – Error and Built-in Exceptions
เมื่อต้องเขียนโปรแกรมที่มีความซับซ้อนมากขึ้น บ่อยครั้งภายในระบบที่ซับซ้อนอาจเกิดข้อผิดพลาดในระหว่างการทำคำสั่งต่างๆ ได้ โดยข้อผิดพลาดนั้นอาจจะเกิดขึ้นได้เนื่องจากหลายสาเหตุ ในบทนี้เราจะมาเรียนรู้เกี่ยวกับรูปแบบของ ข้อผิดพลาดที่เกิดจากการเขียนโปรแกรมไม่ถูกต้องตามหลักภาษา และ ข้อผิดพลาดที่เกิดในระหว่างการดำเนินการของโปรแกรม
-
ข้อผิดพลาดที่เกิดจากการเขียนคำสั่งไม่ถูกต้องตามหลักภาษา
ข้อผิดพลาดที่เกิดจากการเขียนคำสั่งไม่ถูกต้องตามหลักภาษา(syntax error, parsing error) ข้อผิดพลาดแบบนี้จะเกิดในช่วงที่กำลังแปรผลคำสั่งของโปรแกรม ให้เป็นภาษาของคอมพิวเตอร์เพื่อใช้สำหรับดำเนินการทำคำสั่งต่อไป ซึ่งจะมีการแจ้งข้อผิดพลาดและระบุรายละเอียดว่าคำสั่งส่วนใดที่ไม่ถูกต้องตามหลักภาษา
ตัวอย่างการใช้งาน# -*- coding: utf-8 -*- # เรียกใช้งานไลบรารี่ math import math # ฟังก์ชันสำหรับคำนวณระยะทางจากข้อมูลความเร็วต้น, ความเร่งและเวลา def calculate_distance(initial_velocity, acceloration, time) distance = initial_velocity*time + (1.0/2.0)*acceloration*math.pow(time, 2) return distance # คำนวณระยะทางที่ม้าตัวหนึ่งสามารถวิ่งได้ เมื่อเวลาผ่านไป 10 วินาที โดยกำหนดให้ # มีความเร็วต้น 0 เมตร/วินาที และมีความเร่งคงที่ 4 เมตร/(วินาที^2) distance = calculate_distance(0, 4, 10) print(distance) # โปรแกรมทำการปรินต์ค่า # 200.0
จากตัวอย่างโปรแกรมจะเกิดข้อผิดพลาดเนื่องจากเขียนคำสั่งไม่ถูกต้องตามหลักภาษา เนื่องจากคำสั่งสำหรับสร้างฟังก์ชัน “def calculate_distance(initial_velocity, acceloration, time)” นั้น ไม่ได้ใส่เครื่องหมาย “:” ไว้ท้ายประโยค เพื่อระบุการจบเงื่อนไข โปรแกรมจึงเกิดข้อผิดพลาดในระหว่างคอมไพล์ตัวโปรแกรม
โดยฟังก์ชัน calculate_distance() ในตัวอย่างข้างต้นนั้น เป็นฟังก์ชันสำหรับคำนวณระยะทาง(S) ที่ม้าตัวหนึ่งจะวิ่งได้ภายในช่วงเวลาที่ระบุ(t) โดยทราบความเร็วต้นของม้า(u) และ ทราบความเร่งคงที่ของการวิ่งของม้า(a) ซึ่งทำการคำนวณจากสมการเกี่ยวกับการเคลื่อนที่:
S = ut + 1/2at2
S: ระยะทางทั้งหมดของการเคลื่อนที่จากช่วงเวลาที่ระบุ(m)
u: ความเร็วเริ่มต้นของการเคลื่อนที่(m/s)
a: ความเร่งคงที่ของการเคลื่อนที่(m/s2)
t: ระยะเวลาที่ทำการสังเกตุ(s)
ซึ่งสามารถเขียนออกมาได้เป็นแผนภาพดังนี้:

-
ข้อผิดพลาดในระหว่างดำเนินการทำคำสั่งต่างๆ
ข้อผิดพลาดในระหว่างดำเนินการทำคำสั่งต่างๆ ระหว่างการใช้งานโปรแกรม โดยเมื่อเกิดข้อผิดพลาดในรูปแบบนี้ จะทำให้เกิด exception ขึ้นในโปรแกรม ซึ่งข้อผิดพลาดชนิดนี้ สามารถเกิดได้จากหลายเหตุผล ตัวอย่างเช่น เขียนคำสั่งเปิดไฟล์ที่ไม่มีอยู่จริง(FileNotFoundError), ทำการหารด้วยส่วนที่มีค่าเป็น 0 (ZeroDivisionError), การใช้งานโมดูลที่ไม่มีอยู่จริง(ImportError) และอื่นๆ
หากเกิดข้อผิดพลาดที่เกิดขึ้น เกิดในช่วงระหว่างดำเนินการทำคำสั่งต่างๆ อยู่ โปรแกรมจะทำสร้างออบเจ็คชนิด exception เพื่อเก็บรายละเอียดและระบุชนิดของข้อผิดพลาดเหล่านั้น โดยข้อดีของการมี exception เหล่านี้ คือ เราสามารถเขียนโปรแกรมเพิ่มเติมเพื่อใช้ดักจับข้อผิดพลาด โดยระบุชนิดของข้อผิดพลาดที่อาจเกิดขึ้นรูปแบบต่างๆ ไว้ล่วงหน้าได้และจัดการกับข้อผิดพลาดได้อย่างถูกต้องเมาะสม ตามชนิดของข้อผิดพลาดนั้นๆ แต่ถ้าหากเราไม่ได้เขียนคำสั่งเพิ่มเติมไว้จัดการสำหรับกรณีที่มีการเกิดข้อผิดพลาดเหล่านั้นเลย ข้อผิดพลาดก็จะแสดงออกมาในรูป traceback พร้อมกับรายละเอียดที่ทำให้เกิดข้อผิดพลาด
ตัวอย่างการใช้งาน# -*- coding: utf-8 -*- # ฟังก์ชันสำหรับคำนวณความเร็วของรถที่มีความเร็วคงที่(m/s^2)และไม่มีความเร่ง จากข้อมูลระยะทางและเวลาที่ใช้ไป def calculate_velocity(distance, time): velocity = float(distance)/ float(time) return velocity # คำนวณความเร็วของรถซึ่งขับด้วยความเร็วคงที่และไม่มีความเร่ง เมื่อทราบระยะทางที่สามารถเดินทางไปได้และระยะเวลาดังกล่าว velocity = calculate_velocity(1500, 60) print(velocity) # โปรแกรมทำการปรินต์ค่า # 25.0 # คำนวณความเร็วของรถซึ่งขับด้วยความเร็วคงที่และไม่มีความเร่ง เมื่อทราบระยะทางที่สามารถเดินทางไปได้และระยะเวลาดังกล่าว velocity = calculate_velocity(1500, 0) print(velocity) # โปรแกรมทำการปรินต์ค่า # ZeroDivisionError: float division by zero # โปรแกรมทำการปรินต์ค่า # Traceback (most recent call last): # File "test.py", line 16, in <module> # velocity = calculate_velocity(1500, 0) # File "test.py", line 6, in calculate_velocity # velocity = float(distance)/ float(time) # ZeroDivisionError: division by zero
จากตัวอย่างข้างต้นจะเกิดข้อผิดพลาดเนื่องจาก ทำการกำหนดตัวส่วนในการหาร ให้มีค่าเป็น 0 ซึ่งจะทำให้เกิดข้อผิดพลาดชนิด ZeroDivisionError ขึ้น
โดยฟังก์ชัน calculate_velocity() ในตัวอย่างข้างต้นนั้น เป็นฟังก์ชันสำหรับทำการคำนวณหาความเร็วคงที่ของรถยนต์ที่ไม่มีความเร่ง โดยทราบข้อมูลของระยะทางและเวลาที่รถยนต์ดังกล่าวใช้ไประหว่างการเดินทางช่วงเวลาหนึ่ง ซึ่งทำการคำนวณจากสมการเกี่ยวกับการเคลื่อนที่:
S = v*t
โดย
S: ระยะทางของทั้งหมดการเคลื่อนที่จากช่วงเวลาที่ระบุ(m)
v: ความเร็วคงที่ของการเคลื่อนที่(m/s)
t: ระยะเวลาที่ทำการสังเกตุ(s)
ซึ่งสามารถเขียนออกมาได้เป็นแผนภาพดังนี้:

-
Built-in Exception
ใน python จะมี built-in exceptions มาหลายชนิดสำหรับการดักจับข้อผิดพลาดในรูปแบบต่างๆ
ชนิดของ Exception รายละเอียด AssertionError จะเกิดขึ้นเมื่อมีการใช้คำสั่ง assert เพื่อทำการตรวจสอบโปรแกรม แล้วข้อมูลที่ตรวจสอบไม่ตรงกับเงื่อนไขที่กำหนด AttributeError จะเกิดขึ้นเมื่อมีการกำหนดค่าหรือเข้าถึงข้อมูลของคุณลักษณะ(attribute) แล้วเกิดข้อผิดพลาด EOFError จะเกิดขึ้นเมื่อเรียกใช้ฟังก์ชัน input() แต่ข้อมูลในไฟล์ถูกอ่านไปจนถึงตำแหน่งสุดท้ายแล้ว FloatingPointError จะเกิดขึ้นเมื่อการดำเนินการกับเลขทศนิยมเกิดข้อผิดพลาด GeneratorExit จะเกิดขึ้นเมื่อฟังก์ชัน close() ของ generator ถูกเรียกใช้ ImportError จะเกิดขึ้นเมื่อมีการ import โมดูลที่ไม่มีอยู่จริง IndexError จะเกิดขึ้นเมื่อมีการเข้าถึงข้อมูลในลำดับที่อยู่นอกเหนือจากลำดับของช่วงข้อมูลจริง KeyError จะเกิดขึ้นเมื่อ มีการเรียกใช้ข้อมูลจากคีย์ที่ไม่มีอยู่จริงในข้อมูลชนิดดิกชันนารี KeyboardInterrupt จะเกิดขึ้นเมื่อผู้ใช้งานกด interrupt key (ctrl+c หรือ delete) MemoryError จะเกิดขึ้นเมื่อมีหน่วยความจำไม่เพียงพอในระหว่างการดำเนินการ NameError จะเกิดขึ้นเมื่อมีการใช้เรียกใช้ตัวแปรที่ไม่มีอยู่จริงทั้ง local และ global scope NotImplementedError จะเกิดขึ้นเมื่อ จากฟังก์ชันที่ประกาศเป็น abstract นั้นยังไม่ได้ทำการ implement ฟังก์ชันจริงเพื่อใช้งาน OSError จะเกิดขึ้นเมื่อมีการดำเนินการกับระบบแล้วมีข้อผิดพลาดที่เกี่ยวข้องกับระบบปฏิบัติการ OverflowError จะเกิดขึ้นเมื่อผลของการดำเนินการทางคณิตศาสตร์นั้นทำให้เกิดข้อมูลขนาดใหญ่กว่าจะแสดงผลได้ ReferenceError จะเกิดขึ้นเมื่อ weak reference proxy ถูกใช้เพื่อเข้าถึงข้อมูลที่ถูก garbage collect ไปแล้ว RuntimeError จะเกิดขึ้นเมื่อข้อผิดพลาดที่เกิดขึ้นนั้น ไม่สามารถจัดอยู่ในหมวดหมู่เฉพาะอื่นๆ ได้ StopIteration จะเกิดขึ้นเมื่อ มีการเรียกใช้ฟังก์ชัน next() เพื่อจะทำการดึงข้อมูลค่าต่อไป แต่ตำแหน่งดังกล่าวนั้นไม่มีข้อมูลลำดับต่อไปอีก SyntaxError จะเกิดขึ้นจากตัว parser เมื่อเกิดกรณีเกิดข้อผิดพลาดเกี่ยวกับหลักภาษา(syntax) IndentationError จะเกิดขึ้นเมื่อ มีการใช้รูปแบบการย่อหน้า(indent) ไม่ถูกตามหลักภาษา TabError จะเกิดขึ้นเมื่อ รูปแบบย่อยหน้า(indent) มีการใช้แทป(tab) หรือช่องว่างที่ไม่สอดคล้องกัน ทำให้ไม่ถูกต้องตามหลักภาษา SystemError จะเกิดขึ้นเมื่อ ตัวแปรภาษาเจอข้อผิดพลาดที่เกิดจากระบบแต่ไม่รุนแรงถึงขั้นต้องหยุดการดำเนินการโปรแกรมทั้งหมด SystemExit จะเกิดขึ้นเมื่อ มีการเรียกใช้ฟังก์ชัน system.exit() แล้วเกิดข้อผิดพลาด TypeError จะเกิดขึ้นเมื่อ ฟังก์ชันหรือตัวดำเนินการนั้นใดๆ ต้องดำเนินการกับออบเจ็คที่ไม่ถูกต้องตามชนิดของออบเจ็คที่ฟังก์ชันหรือตัวดำเนินการเหล่านั้นรองรับ UnboundLocalError จะเกิดขึ้นเมื่อ มีการอ้างอิงกับตัวแปรชนิด local สำหรับฟังก์ชัน หรือ method แต่ไม่มีข้อมูลใดอ้างอิงกับตัวแปรดังกล่าว UnicodeError จะเกิดขึ้นเมื่อการ encode/decode unicode เกิดข้อผิดพลาดในระหว่างดำเนินการ UnicodeEncodeError จะเกิดขึ้นเมื่อ ระหว่างการ encode unicode เกิดข้อผิดพลาดในระหว่างดำเนินการ UnicodeDecodeError จะเกิดขึ้นเมื่อ ระหว่างการ decode unicode เกิดข้อผิดพลาดในระหว่างดำเนินการ ValueError จะเกิดขึ้นเมื่อฟังก์ชันได้รับข้อมูลสำหรับตัวแปรมาตรงตามชนิดสามารถรองรับได้ แต่ค่าที่ได้รับไม่เหมาะสมทำให้เกิดข้อผิดพลาด ZeroDivisionError จะเกิดขึ้นเมื่อการใช้ ตัวส่วนของการหารมีค่าเป็น 0
เครื่องมือในการวาดรูปประกอบ: draw.io
ที่มา icon รูปรถ: Mello จาก iconfinder
ที่มา icon รูปม้า: Iconnice จาก flaticon is licensed by CC 3.0 BY
