พฤติกรรมการลองใช้อย่างอื่นที่แปลกประหลาดในท้ายที่สุดด้วยคำสั่ง Return


91

นี่คือรหัสบางส่วนที่ทำงานผิดปกติ นี่เป็นเวอร์ชันที่เรียบง่ายของพฤติกรรมที่ฉันเขียน สิ่งนี้จะยังคงแสดงให้เห็นถึงพฤติกรรมแปลก ๆ และฉันมีคำถามเฉพาะบางอย่างเกี่ยวกับสาเหตุที่เกิดขึ้น

ฉันใช้ Python 2.6.6 บน Windows 7

def demo1():
    try:
        raise RuntimeError,"To Force Issue"
    except:
        return 1
    else:
        return 2
    finally:
        return 3

def demo2():
    try:
        try:
            raise RuntimeError,"To Force Issue"
        except:
            return 1
        else:
            return 2
        finally:
            return 3
    except:
        print 4
    else:
        print 5
    finally:
        print 6

ผล:

>>> print demo1()
3
>>> print demo2()
6
3
  • เหตุใดการสาธิตจึงส่งคืน 3 แทนที่จะเป็น 1
  • เหตุใดการสาธิตสองการพิมพ์ 6 แทนที่จะเป็นการพิมพ์ 6 w / 4 หรือ 5

คำตอบ:


128

เนื่องจากfinallyคำสั่งได้รับการรับรองว่าจะดำเนินการ (โดยสันนิษฐานว่าไม่มีไฟฟ้าดับหรือสิ่งใดที่อยู่นอกเหนือการควบคุมของ Python) ซึ่งหมายความว่าก่อนที่ฟังก์ชันจะสามารถส่งคืนฟังก์ชันจะต้องเรียกใช้บล็อกในที่สุดซึ่งจะส่งคืนค่าที่แตกต่างกัน

หลามเอกสารรัฐ:

เมื่อมีการดำเนินการคำสั่ง return, break หรือ continue ในชุดคำสั่ง try …ในที่สุดประโยคสุดท้ายก็จะถูกเรียกใช้ด้วยเช่นกัน

ค่าส่งคืนของฟังก์ชันถูกกำหนดโดยคำสั่งส่งคืนสุดท้ายที่ดำเนินการ เนื่องจากประโยคสุดท้ายจะดำเนินการเสมอคำสั่ง return ที่ดำเนินการในประโยคสุดท้ายจะเป็นประโยคสุดท้ายที่ดำเนินการเสมอ:

ซึ่งหมายความว่าเมื่อคุณพยายามที่จะกลับมาfinallyบล็อกจะถูกเรียกโดยส่งคืนค่าแทนค่าที่คุณเคยมี


4
ทำไม 5 ไม่พิมพ์ในตัวอย่างที่สอง นี่ยังอธิบายได้ไม่ดีเท่าที่ฉันคิด ผลตอบแทนที่ตอบได้ดี แต่ทำไม 5 ในตัวอย่างที่สองไม่พิมพ์
Joran Beasley

5
โอ้ฉันคิดว่าฉันคิดออกแล้วว่าผลตอบแทนในการลองครั้งแรกทำให้มันกระโดดไปด้านนอกในที่สุด
Joran Beasley

2
ถูกต้องเพราะfinallyบล็อกจะทำงานตลอดเวลา
Gareth Latty

2
ในการสาธิตที่สองทำไมมันถึงดำเนินการที่ซ้อนกันในที่สุดเตะออกไปข้างนอกในที่สุดจากนั้นกลับเข้าไปในรังในที่สุดเพื่อจบการกลับมาแทนที่จะกลับมาไม่มีจากภายนอก
Kyle Owens

1
เนื่องจากเมื่อreturnมีการเรียกคำสั่ง Python จะตรวจสอบfinallyคำสั่งเปิดที่จำเป็นต้องดำเนินการ (ดูคำพูดด้านบน)
Gareth Latty

7

คำสั่งดำเนินการคือ:

  1. พยายามบล็อกทั้งหมดที่เสร็จสมบูรณ์ตามปกติ -> สุดท้ายบล็อก -> สิ้นสุดฟังก์ชัน
  2. ลองบล็อกรันและเข้าสู่ข้อยกเว้น A -> ในที่สุดบล็อก -> ฟังก์ชันจะสิ้นสุดลง
  3. ลองบล็อกสร้างค่าส่งคืนและเรียกกลับ -> สุดท้ายบล็อก -> ค่าส่งคืนป๊อปอัป -> สิ้นสุดฟังก์ชัน

ดังนั้นผลตอบแทนใด ๆ ในบล็อกสุดท้ายจะสิ้นสุดขั้นตอนล่วงหน้า

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.