โมดูลบริบทของไลบรารีมาตรฐานของ Python กำหนดคลาส ContextManager ซึ่งวัตถุจัดการทรัพยากรภายในโปรแกรมอย่างเหมาะสม Python มีคีย์เวิร์ดที่ทำงานร่วมกับตัวจัดการบริบท วัตถุไฟล์ (ซึ่งส่งคืนโดยฟังก์ชัน open() ในตัว) รองรับ ContextManager API ดังนั้นเราจึงมักพบคีย์เวิร์ดที่ใช้ขณะทำงานกับไฟล์
บล็อกโค้ดต่อไปนี้จะเปิดไฟล์และเขียนข้อมูลบางส่วนในนั้น หลังจากการดำเนินการสิ้นสุดลง ไฟล์จะถูกปิด ความล้มเหลวของตัวอธิบายไฟล์ที่มีแนวโน้มว่าจะรั่วไหลซึ่งนำไปสู่ความเสียหายของไฟล์
f = open("file.txt","w") f.write("hello world") f.close()
อย่างไรก็ตาม การดำเนินการไฟล์เดียวกันทำได้โดยใช้ความสามารถของตัวจัดการบริบทของไฟล์โดยใช้ไวยากรณ์ต่อไปนี้
with open("file.txt","w") as f: f.write("hello world") print ("file is closed")
ตามที่กล่าวไว้ข้างต้น วัตถุไฟล์ใช้ ContextManager เปิดใช้งานด้วยคีย์เวิร์ด บล็อก with มีคำสั่งที่จะประมวลผลสำหรับอ็อบเจ็กต์ไฟล์ ทันทีที่บล็อกสิ้นสุดลง วัตถุไฟล์จะถูกปิดโดยอัตโนมัติ (ไม่จำเป็นต้องเรียกเมธอด close() อย่างชัดแจ้ง) วัตถุใดๆ ที่อยู่ภายใต้การบล็อกจะทำงานเฉพาะภายในบล็อกและจะถูกกำจัดทิ้งทันทีที่สิ้นสุด
คลาส ContextManager มีสองวิธีที่จำเป็น __enter__() และ __exit__()
__enter__() − จะถูกเรียกเมื่อเริ่มบล็อก แสดงว่าโปรแกรมได้เข้าสู่บริบทรันไทม์ที่เกี่ยวข้องกับวัตถุนี้
__exit__() − ถูกเรียกเมื่อบล็อคหมด แสดงว่าโปรแกรมออกจากบริบทรันไทม์ที่เกี่ยวข้องกับวัตถุนี้
ออบเจ็กต์ไฟล์ก็มีสองวิธีนี้เช่นกัน ซึ่งสามารถยืนยันได้โดยทำตามเซสชันล่าม
>>> f = open("file.txt","w") >>> f.__enter__() <_io.TextIOWrapper name = 'file.txt' mode = 'w' encoding = 'cp1252'> >>> f.write("hello world") 11 >>> f.__exit__() >>> f.write("hello world") Traceback (most recent call last): File "<pyshell#10>", line 1, in <module> f.write("hello world") ValueError: I/O operation on closed file.
เมื่อเรียกเมธอด __exit__() ไฟล์จะถูกปิด นั่นเป็นสาเหตุที่ ValueError ปรากฏขึ้นเมื่อเราพยายามเขียนข้อมูลบางส่วนไปยังไฟล์หลังจากที่ปิดแล้ว
รับด้านล่างเป็นการใช้งานทั่วไปของบริบทManager ขั้นแรก เรากำหนดคลาสด้วยเมธอด __enter__() และ __exit__() และเปิดใช้งานระบบบริบทสำหรับอ็อบเจ็กต์โดยใช้คำสั่ง
import contextlib class WithExample: def __init__(self): print ("object initialized") def __enter__(self): print ("entered context") def __exit__(self, *args): print ("exited context") with WithExample() as w: print ('this is a contextlib example') print ('used by with statement') print ('end of with block')
ผลลัพธ์แสดงให้เห็นว่าทันทีที่บล็อก with เริ่มทำงาน เมธอด __enter__() จะถูกดำเนินการ คำสั่งภายในบล็อกได้รับการประมวลผล เมื่อบล็อกสิ้นสุดลง เมธอด __exit__() จะถูกเรียกโดยอัตโนมัติ
object initialized entered context this is a contextlib example used by with statement exited context end of with block
โมดูล Contextlib มี @contextmanager มัณฑนากร ด้วยความช่วยเหลือซึ่งเราสามารถเขียนฟังก์ชันโรงงานตามตัวสร้างเพื่อรองรับคำสั่งโดยอัตโนมัติ การจัดการบริบทของไฟล์วัตถุด้วยมัณฑนากรมีดังนี้ -
from contextlib import contextmanager @contextmanager def openfile(name): try: f = open(name, 'w') yield f finally: f.close() with openfile(file.txt') as f: f.write('hello world') print ('file is closed')
ContextManager จึงเป็นคุณสมบัติที่มีประโยชน์มากของ Python สำหรับการจัดการทรัพยากรในโปรแกรมอย่างมีประสิทธิภาพ