มีเหตุผลหนึ่งข้อว่าทำไมถึงต้องการสิ่งต่อไปนี้:
with open('filename.txt') as fp:
for line in fp:
print line
พวกเราทุกคนต่างก็ใจแตกโดยรูปแบบการนับการอ้างอิงที่ค่อนข้างแน่นอนของ CPython สำหรับการเก็บขยะ อื่น ๆ การใช้งานสมมุติของ Python จะไม่จำเป็นต้องปิดไฟล์ "เร็วพอ" โดยไม่มีwith
บล็อกหากพวกเขาใช้รูปแบบอื่น ๆ เพื่อเรียกคืนหน่วยความจำ
ในการใช้งานดังกล่าวคุณอาจได้รับข้อผิดพลาด "เปิดไฟล์มากเกินไป" จากระบบปฏิบัติการหากรหัสของคุณเปิดไฟล์เร็วกว่าที่ผู้รวบรวมขยะเรียกการเรียกใช้ finalizers ในการจัดการไฟล์ orphaned วิธีแก้ปัญหาตามปกติคือเรียกใช้ GC ทันที แต่นี่เป็นการแฮ็คที่น่ารังเกียจและต้องทำโดยทุกฟังก์ชั่นที่อาจพบข้อผิดพลาดรวมถึงที่อยู่ในไลบรารี ช่างฝันร้ายอะไร
หรือคุณสามารถใช้with
บล็อก
คำถามโบนัส
(หยุดอ่านเดี๋ยวนี้หากสนใจเฉพาะจุดประสงค์ของคำถาม)
เหตุใดจึงไม่รวมอยู่ในโปรโตคอลตัววนซ้ำสำหรับวัตถุไฟล์
นี่เป็นคำถามแบบอัตนัยเกี่ยวกับการออกแบบ API ดังนั้นฉันจึงมีคำตอบแบบอัตนัยในสองส่วน
ในระดับความรู้สึกผิดปกติเพราะมันทำให้โปรโตคอลตัววนซ้ำทำสองสิ่งแยกกัน - ทำซ้ำข้ามบรรทัดและปิดตัวจัดการไฟล์ - และบ่อยครั้งที่ความคิดที่ไม่ดีที่จะทำให้ฟังก์ชั่นดูเรียบง่ายนั้นทำได้สองอย่าง ในกรณีนี้มันรู้สึกไม่ดีโดยเฉพาะอย่างยิ่งเนื่องจากตัววนซ้ำเกี่ยวข้องกับวิธีการทำงานแบบกึ่งคุณค่าตามเนื้อหาของไฟล์ แต่การจัดการตัวจัดการไฟล์เป็นงานแยกต่างหากอย่างสมบูรณ์ การทำให้ทั้งคู่ล่องหนกลายเป็นการกระทำที่น่าแปลกใจสำหรับคนที่อ่านรหัสและทำให้ยากขึ้นที่จะให้เหตุผลเกี่ยวกับพฤติกรรมของโปรแกรม
ภาษาอื่น ๆ ได้ข้อสรุปเดียวกัน Haskell จีบสั้น ๆ กับสิ่งที่เรียกว่า "lazy IO" ซึ่งช่วยให้คุณสามารถวนซ้ำไฟล์และปิดมันโดยอัตโนมัติเมื่อคุณไปถึงจุดสิ้นสุดของสตรีม ผู้ใช้ส่วนใหญ่ได้ย้ายไปที่การจัดการทรัพยากรที่ชัดเจนมากขึ้นเช่น Conduit ซึ่งทำงานเหมือนwith
บล็อกใน Python
ในระดับเทคนิคมีบางสิ่งที่คุณอาจต้องการทำกับตัวจัดการไฟล์ใน Python ซึ่งจะไม่ทำงานเช่นกันหากการวนซ้ำปิดตัวจัดการไฟล์ ตัวอย่างเช่นสมมติว่าฉันต้องวนซ้ำไฟล์สองครั้ง:
with open('filename.txt') as fp:
for line in fp:
...
fp.seek(0)
for line in fp:
...
ในขณะที่นี่เป็นกรณีการใช้งานที่ไม่ธรรมดาลองพิจารณาข้อเท็จจริงที่ว่าฉันอาจเพิ่งเพิ่มโค้ดสามบรรทัดที่ด้านล่างลงในฐานรหัสที่มีอยู่ซึ่ง แต่เดิมมีสามบรรทัดแรกสุด หากการวนซ้ำปิดไฟล์ฉันจะไม่สามารถทำเช่นนั้นได้ ดังนั้นการแยกการวนซ้ำและการจัดการทรัพยากรทำให้การเขียนโค้ดเป็นโปรแกรม Python ที่ทำงานได้ง่ายขึ้น
การเรียบเรียงเป็นหนึ่งในคุณสมบัติการใช้งานที่สำคัญที่สุดของภาษาหรือ API