โมดูลบริบทของไลบรารีมาตรฐานของ 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 สำหรับการจัดการทรัพยากรในโปรแกรมอย่างมีประสิทธิภาพ