
try, except และ else ไป แต่จริงๆแล้วโครงสร้างการจัดการกับข้อยกเว้นนี้ยังประกอบไปด้วยอีกตัวคือ finally ซึ่งอาจใช้ไม่บ่อยและไม่มีความสำคัญมาก จึงไม่ได้เขียนในเนื้อหาหลักแต่แยกมาเขียนเป็นเนื้อหาเสริม อาจไม่ได้จำเป็นต้องใช้งานจริง แต่ถ้ารู้ไว้เวลามีคนใช้ก็จะเข้าใจถึงความหมายtry และ except เป็นหลัก โดยใส่คำสั่งที่ระวังว่าอาจจะเกิดข้อยกเว้นไว้ใน try และใส่คำสั่งที่จะให้ทำเมื่อมีข้อยกเว้นลงใน except แต่นอกจากนั้นแล้วยังสามารถใส่ finally ต่อลงไปได้อีก โดยส่วนที่อยู่ใน finally นั้นจะทำตอนท้ายสุดอย่างแน่นอนไม่ว่าจะเกิดอะไรขึ้นtry, except พร้อม finally อาจเขียนได้ดังนี้ try:
คำสั่งที่กังวลว่าจะเกิดข้อยกเว้นขึ้นได้
except:
คำสั่งสำหรับจัดการกับข้อยกเว้น
finally:
คำสั่งที่จะให้ทำงานเสมอตอนท้ายที่สุด
try และ except แล้วละก็ มีความจำเป็นอะไรต้องเขียนใน finally ด้วยหรือ? เขียนข้างนอกมันก็ทำงานเหมือนกันไม่ใช่หรือ?try:
print('เดินไปโรงเรียน')
raise Exception('หกล้มหัวคะมำ')
except Exception as e:
print(e)
print('ลุกขึ้นมาแล้วเดินต่อ')
finally:
print('ในที่สุดก็ถึงโรงเรียน')
print('ตั้งใจเรียน')
เดินไปโรงเรียน หกล้มหัวคะมำ ลุกขึ้นมาแล้วเดินต่อ ในที่สุดก็ถึงโรงเรียน ตั้งใจเรียน
print('ในที่สุดก็ถึงโรงเรียน') และ print('ตั้งใจเรียน') ก็ทำตอนท้ายไม่ว่าจะเกิดข้อยกเว้นหรือไม่ก็ตามfinally ในกรณีแบบนี้ไม่ได้มีความจำเป็น เพราะสามารถเขียนข้างนอกได้finally กับการเขียนข้างนอกจะเกิดขึ้นได้ในหลายกรณีด้วยกัน ในกรณีแบบนั้นจึงจะมีความหมายที่จะใช้ finally ซึ่งจะยกตัวอย่างต่อไปนี้finally ก็คือใช้ใส่คำสั่งที่ยังไงก็ต้องการให้ทำตอนท้ายสุดอย่างแน่นอนไม่ว่าจะเกิดอะไรขึ้นก็ตามexcept ด้วยtry ข้อยกเว้นนั้นก็จะถูกยกเลิกแล้วโปรแกรมก็จะทำงานต่อไปได้โดยเข้าสู่โครงสร้าง except ไปทำคำสั่งในนั้น แต่ว่าถ้าหากภายในส่วนของ except นั้นยังเกิดข้อยกเว้นขึ้นมาอีก คราวนี้โปรแกรมจะหยุดทำงานไปจริงๆ และแน่นอนว่าพอเป็นแบบนี้แล้วคำสั่งที่ถูกเขียนอยู่ต่อจากนั้นก็จะไม่ทำงานfinally แล้วละก็ คำสั่งนั้นจะทำงานขึ้นมาก่อนที่โปรแกรมจะหยุดทำงานไปจริงๆtry:
raise Exception
except:
raise Exception
finally:
print('ส่วนนี้จะทำงาน')
print('ส่วนนี้ไม่ทำงาน')
finally ไม่ได้ช่วยให้ข้อยกเว้นที่เกิดขึ้นในโครงสร้าง except ถูกยกเลิกไป เพียงแต่อย่างน้อยก็ช่วยให้ทำคำสั่งบางอย่างที่ต้องการทำให้ได้ก่อนแม้ว่าโปรแกรมจะมีอันต้องหยุดลงfinally แบบนี้ก็จะมั่นใจได้ว่าจะทำงานจริงๆเสมอfinally ก็คือเมื่อจะใช้ try โดยไม่ใช่ excepttry จะใช้กับ except เสมอ ไม่สามารถเขียนเดี่ยวๆได้ แม้ว่าจะไม่ได้มีเนื้อหาอะไรที่ต้องการให้จัดการเมื่อเจอข้อยกเว้นก็ตามtry ยังใช้คู่กับ finally เฉยๆได้ด้วย โดยที่ไม่มี except แบบนี้ก็จะกลายเป็นโครงสร้าง try finallyexcept ละก็ ข้อยกเว้นที่เกิดขึ้นใน try ก็จะไม่ถูกยกเลิกและโปรแกรมก็จะหยุดการทำงานtry finally ก็คือเมื่อมีคำสั่งบางอย่างที่ต้องการให้ทำแม้ว่าจะมีข้อยกเว้นใน try แต่ว่าไม่จำเป็นต้องหักล้างข้อยกเว้นนั้น แต่ให้โปรแกรมหยุดทำงานไปtry except ละก็อาจเขียนในลักษณะนี้ try:
# คำสั่งบางอย่าง
except Exception as e:
# คำสั่งที่ต้องการให้ทำเมื่อเกิดข้อยกเว้นใน try ก่อนจะหยุดการทำงาน
raise e # ปล่อยให้เกิดข้อยกเว้นแล้วหยุดการทำงานไป
try finally ก็จะเขียนได้แบบนี้ ซึ่งสั้นลง try:
# คำสั่งบางอย่าง
finally:
# คำสั่งที่ต้องการให้ทำเมื่อเกิดข้อยกเว้นใน try ก่อนจะหยุดการทำงาน
def a_han_b(a,b):
try:
print(a/b)
finally:
print('หารเสร็จแล้ว')
a_han_b(3,0)
หารเสร็จแล้ว ปรากฎขึ้นมาก่อนที่จะตามมาด้วยข้อความประกาศว่ามีข้อยกเว้นเกิดขึ้นfinally นั้นไม่ได้มีส่วนช่วยในการลบล้างข้อยกเว้นที่เกิดขึ้น ถึงคำสั่งในโครงสร้าง finally จะทำงานก่อนเกิดข้อยกเว้น แต่ยังไงหลังจากนั้นโปรแกรมก็จะหยุดลง แต่อย่างไรก็ตาม ถ้าหาก finally ถูกใช้ภายในโครงสร้างฟังก์ชัน มันสามารถทำให้ข้อยกเว้นที่เกิดขึ้นถูกลบล้างได้จริงๆ โดยการใส่ return ในนั้น เช่น
def f():
try:
raise Exception
finally:
return
f()
except อีกก็ด้วย
def f():
try:
raise Exception
except:
raise Exception
finally:
return
f()
try แต่เพราะมี return อยู่ใน finally ทำให้ข้อยกเว้นถูกลบล้างหายไปและโปรแกรมก็ทำงานไปได้ตามปกติreturn ลงไปใน finally ก็จะไม่หยุดการทำงานกลางคันไม่ว่าจะเกิดข้อยกเว้นในโครงสร้าง try หรือ except ก็ตามreturn ภายในฟังก์ชันขึ้นมา การทำงานในฟังก์ชั้นนั้นจะสิ้นสุดลงทันทีtry finally ในฟังก์ชัน แล้วเกิดการ return ภายในโครงสร้าง try สิ่งที่เขียนไว้ใน finally ก็ยังจะทำงานด้วยตอนจบฟังก์ชันdef f():
try:
return
finally:
print('คำสั่งในส่วนนี้ทำงานก่อนจบฟังก์ชัน')
f()
finally ที่ว่ามีใช้เพื่อยืนยันว่าจะทำงานอย่างแน่นอนตอนท้ายสุดนั้น ไม่ใช่แค่ใช้ในการจัดการข้อยกเว้นเท่านั้น แต่ยังใช้ในกรณีที่ไม่เกี่ยวกับข้อยกเว้นได้ด้วย คือใช้กับฟังก์ชันเมื่อมีคำสั่งที่ต้องการให้ทำงานเสมอตอนจบฟังก์ชันreturn ภายใน except ก็เช่นกัน ยังไงคำสั่งในโครงสร้าง finally ก็ทำงานdef f():
try:
raise Exception
except:
return
finally:
print('คำสั่งในส่วนนี้ทำงานก่อนจบฟังก์ชัน')
f()
return เกิดขึ้นทั้งในโครงสร้าง try, except และ finally แล้วจะเป็นอย่างไรdef f(x):
try:
if(x == 0):
return 'พยายาม'
else:
raise Exception
except:
return 'ยกเว้น'
finally:
return 'จบแล้ว'
print(f(0)) # จบแล้ว
print(f(1)) # จบแล้ว
return ใน finally ก็จะถูกนำไปใช้เสมอ แม้ว่าก่อนหน้านั้นจะเกิดการ return ขึ้นก่อนภายใน try หรือ except ก็ตาม แต่หลังจากนั้น finally ก็ทำงานขึ้นมาแล้วก็เจอ return ในนั้นแล้วค่าเดิมที่ return ไปก็จะถูกเขียนทับไปfinally นั้นช่างแข็งแกร่งreturn ภายใน finally เพราะแม้ว่าจะไม่ผิดไวยากรณ์ แต่มักจะนำไปสู่ผลลัพธ์ที่ไม่ได้คาดหวัง ดังนั้นจึงแค่รู้ไว้เฉยๆก็พอว่าถ้าทำแบบนี้แล้วจะเกิดผลแบบนี้ขึ้นได้ แต่ว่าถ้าไม่จำเป็นก็ไม่น่าจะนำไปใช้จริงๆfinally นั้นมีความหมายยังไง ใช้งานยังไงบ้างfinally ว่าเป็น "ส่วนที่จะทำงานไม่ว่าจะเกิดข้อยกเว้นหรือไม่" ซึ่งการอธิบายแบบนี้แม้ว่าจะไม่ผิด แต่ก็ไม่สมบูรณ์ เพราะถ้าแค่นั้นจริงๆก็ไม่ได้มีความจำเป็นอะไรที่จะต้องใช้ finally แค่เขียนไว้ด้านนอกก็ได้เหมือนกันfinally เป็นอะไรที่มากกว่านั้น ดังนั้นถ้าจะให้ดีจริงๆควรรอธิบายเสริมในส่วนนี้ไปด้วย เช่นอาจอธิบายว่าเป็น "ส่วนที่จะทำงานเสมอในท้ายที่สุดแม้ว่าจะเกิดข้อยกเว้นหรือการ return ขึ้นใน try หรือ except"ติดตามอัปเดตของบล็อกได้ที่แฟนเพจ