คุณมักจะได้ยินว่า Python สนับสนุนสไตล์EAFP ("ง่ายกว่าที่จะขอการให้อภัยมากกว่าการอนุญาต") เหนือสไตล์LBYL ("ดูก่อนที่คุณจะกระโดด") สำหรับฉันมันเป็นเรื่องของประสิทธิภาพและความสามารถในการอ่าน
ในตัวอย่างของคุณ (พูดว่าแทนที่จะส่งคืนรายการหรือสตริงว่างเปล่าฟังก์ชันจะส่งคืนรายการหรือNone
) ถ้าคุณคาดหวังว่า 99% ของเวลาresult
จะมีสิ่งที่ทำซ้ำได้จริงฉันจะใช้try/except
วิธีนี้ มันจะเร็วขึ้นถ้ามีข้อยกเว้นพิเศษจริงๆ ถ้าresult
เป็นNone
กว่า 50% ของเวลาแล้วใช้if
อาจจะดีกว่าคือ
เพื่อรองรับสิ่งนี้ด้วยการวัดเพียงเล็กน้อย:
>>> import timeit
>>> timeit.timeit(setup="a=1;b=1", stmt="a/b") # no error checking
0.06379691968322732
>>> timeit.timeit(setup="a=1;b=1", stmt="try:\n a/b\nexcept ZeroDivisionError:\n pass")
0.0829463709378615
>>> timeit.timeit(setup="a=1;b=0", stmt="try:\n a/b\nexcept ZeroDivisionError:\n pass")
0.5070195056614466
>>> timeit.timeit(setup="a=1;b=1", stmt="if b!=0:\n a/b")
0.11940114974277094
>>> timeit.timeit(setup="a=1;b=0", stmt="if b!=0:\n a/b")
0.051202772912802175
ดังนั้นในขณะที่if
คำสั่งจะมีค่าใช้จ่ายเสมอคุณเกือบจะเป็นอิสระในการตั้งค่าtry/except
บล็อก แต่เมื่อException
เกิดขึ้นจริงค่าใช้จ่ายจะสูงขึ้นมาก
คุณธรรม:
- มันใช้ได้อย่างสมบูรณ์ (และ "pythonic") เพื่อใช้
try/except
สำหรับการควบคุมการไหล
- แต่มันสมเหตุสมผลที่สุดเมื่อ
Exception
s นั้นยอดเยี่ยมจริง ๆ
จาก Python docs:
EAFP
ง่ายต่อการขอการอภัยมากกว่าการอนุญาต รูปแบบการเขียนแบบ Python ทั่วไปนี้จะสมมติว่ามีคีย์หรือคุณสมบัติที่ถูกต้องและจับข้อยกเว้นหากสมมติฐานพิสูจน์ว่าผิด สไตล์ที่สะอาดและรวดเร็วนี้โดดเด่นด้วยการปรากฏตัวของหลายคน
try
และexcept
งบ เทคนิคนี้ขัดแย้งกับ
สไตล์LBYLซึ่งใช้ร่วมกับภาษาอื่น ๆ เช่น C