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
โดยไม่ใช่ except
try
จะใช้กับ except
เสมอ ไม่สามารถเขียนเดี่ยวๆได้ แม้ว่าจะไม่ได้มีเนื้อหาอะไรที่ต้องการให้จัดการเมื่อเจอข้อยกเว้นก็ตามtry
ยังใช้คู่กับ finally
เฉยๆได้ด้วย โดยที่ไม่มี except
แบบนี้ก็จะกลายเป็นโครงสร้าง try
finally
except
ละก็ ข้อยกเว้นที่เกิดขึ้นใน 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"ติดตามอัปเดตของบล็อกได้ที่แฟนเพจ