Python 3.14 กับ Try..Except..Finally
By Arnon Puitrakul - 30 มิถุนายน 2025
เมื่อไม่กี่วันก่อน ไปนั่งอ่าน Feature ใหม่บน Python 3.14 แล้วเจออันนึงที่น่าสนใจมาก ๆ คือ PEP765 มันเป็นปัญหาที่เราเข้าไปอ่านแล้ว ห่ะ เรามีคนทำแบบนั้นด้วยเหรอวะ ปรากฏว่า แมร่งมีจริงแล้วออกมาแก้กันแล้ว ในบทความนี้เราจะมาเล่าให้อ่านว่า มันคืออะไร และเขาแก้ปัญหานี้อย่างไร
ไม่เคยคิดว่าจะมีคนเขียน Code แบบนี้ เหนือชั้นเกิ้น !
try:
//do sth
raise Exception("Hehe")
else:
// do sth
print("You readed the else block")
except Exception:
// do sth
print("You reached the base exception block")
finally:
print("You reached the finally block")เราขอเริ่มจาก Snippet ด้านบนนี้ก่อน คิดว่า หากเราเอาไปรัน คิดว่ามันจะออกอะไร มันก็ควรจะออกว่า มันเข้าไปใน Base Exception Block และ Finally Block แน่นอน เพราะตามกฏคือ ไม่ว่าจะเกิดอะไรขึ้นก็ตามสิ่งที่อยู่ใน Finally จะถูกรันเสมอไม่ว่าจะโดน Exception ดักใน except Block หรือจะไม่มีตัวไหนโดนจนต้องไปโดน else Block
def danger_fn () :
try:
raise Exception("Hehe")
except Exception :
return 1
finally:
return 0งั้นเราลองมาพิจารณา Snippet ด้านบนนี้กัน ถ้าเราไปรัน คิดว่าคำสั่ง danger_fn() ควรจะ Return อะไรกลับมา ระหว่าง 0 และ 1 ถ้ามองตามสามัญสำนึก มันผ่านอันไหนก่อน มันก็น่าจะออกก่อน ดังนั้นมันควรจะต้องออก 1 อย่างแน่นอน แต่ถ้าเราลองเอาไปรันดู ผลมันไปออก 0 แทนอะสิ แสดงว่า Finally มันมีศักดิ์สูงกว่าสิ่งที่อยู่ใน Except ทำให้มัน Override ของใน Except ได้หมดเลย
for i in range(10):
try :
if i == 2 :
raise Exception("i should not equal to 2")
else:
print(f"{i}\n")
except Exception :
break
finally :
continueแล้วถ้าเป็นอันนี้ละ เราบอกว่า ถ้า i เป็น 2 มันควรจะ Raise Exception แล้ว Break ออกไปเลย แต่กลายเป็นว่า Continue มันมีอำนาจเหนือกว่า เลยทำให้ Loop ยังคงรันไปต่อจนจบได้ ซึ่งเอาเข้าจริง มันไม่ควรจะเกิดขึ้นเท่าไหร่
Syntax Warning ใน Python 3.14
บอกกันตามตรงว่า การเขียนพวก break, continue และ return ใน finally เป็นอะไรที่แอบอันตรายพอสมควรถ้าไม่ระวังเลยแหละ ทำให้มีการเปลี่ยนแปลงเพื่อป้องกันเรื่องนี้ใน Python 3.14 คือ หากเรามีการเขียน break, continue และ return ภายใน finally มันจะเตือน SyntaxWarning ขึ้นมาให้เราทำการแก้ไข
เท่าที่เราไปอ่านใน Reddit และ Forum ต่าง ๆ มีบางคน Raise ประเด็นที่น่าสนใจว่า มันควรที่จะทำให้เราสามารถ Supress Warning ตัวนี้ได้ อาจจะเป็นการใส่ Decoration เพื่อบอก หรือกระทั่งการใส่ความสามารถนี้เข้าไปที่ Linter แทน ส่วนใหญ่ให้เหตุผลว่า เพราะบางครั้งมันจำเป็นต้องทำแบบนี้ ซึ่งเราอ่านแล้วก็.... เอ่อ เราทำแบบนี้ด้วยเหรอวะ...
สรุป
เอาจริง ๆ นะ เราพึ่งเคยได้ยินคนที่เขียนอะไรแบบนี้ใน Finally เหมือนกัน จากใน PEP765 ที่เขาไปหามา ก็บอกอยู่นะว่า มันไม่ได้มีอะไรพวกนี้เยอะเท่าไหร่ แค่คิดว่า ถ้ามันเกิดขึ้น ฟิล ๆ ว่า คนเขียนสติไม่ค่อยดี อาจจะเมา ฟิล ๆ ดื่มไปทำงานไปบิวท์อารมณ์ม่วนจอย ๆ บั้นเด้าเวลาทำงานแล้วพลาดอะไรแบบนั้นมากกว่า การเปลี่ยนแปลงเล็ก ๆ นี้อย่างน้อยก็ทำให้ถ้าเรามีระบบการตรวจสอบ Warning ที่ดีก่อน Push Code ขึ้นไป มันก็จะช่วยกรองอะไรแบบนี้ออกไปได้เยอะ และป้องกันปัญหาที่อาจจะเกิดขึ้นโดยที่เราไม่รู้ตัว และถ้ามันเกิดขึ้น พูดตรง ๆ ว่า มัน Debug ยากมากจริง



