पायथन की स्टैंडर्ड लाइब्रेरी का contextlib मॉड्यूल ContextManager क्लास को परिभाषित करता है जिसका ऑब्जेक्ट प्रोग्राम के भीतर संसाधनों को ठीक से मैनेज करता है। पायथन में with कीवर्ड होता है जो कॉन्टेक्स्ट मैनेजर्स के साथ काम करता है। फ़ाइल ऑब्जेक्ट (जो बिल्ट-इन open() फ़ंक्शन द्वारा लौटाया जाता है) ContextManager API को सपोर्ट करता है। इसलिए हम अक्सर फ़ाइलों के साथ काम करते समय with कीवर्ड का उपयोग देखते हैं।
निम्न कोड ब्लॉक एक फ़ाइल खोलता है और इसमें कुछ डेटा लिखता है। ऑपरेशन खत्म होने के बाद, फ़ाइल बंद हो जाती है, ऐसा न करने पर फ़ाइल डिस्क्रिप्टर लीक होने की संभावना होती है जिससे फ़ाइल करप्शन हो सकता है।
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 कीवर्ड द्वारा सक्षम होता है। with ब्लॉक में फ़ाइल ऑब्जेक्ट के लिए प्रोसेस किए जाने वाले स्टेटमेंट्स होते हैं। जैसे ही with ब्लॉक खत्म होता है, फ़ाइल ऑब्जेक्ट स्वचालित रूप से बंद हो जाता है (close() मेथड को स्पष्ट रूप से कॉल करने की आवश्यकता नहीं)। with ब्लॉक के अधीन कोई भी ऑब्जेक्ट केवल ब्लॉक के अंदर सक्रिय रहेगा और इसके अंत में तुरंत डिस्पोज़ हो जाएगा।
ContextManager क्लास में दो आवश्यक मेथड्स __enter__() और __exit__() होते हैं:
__enter__() - जब with ब्लॉक शुरू होता है तो कॉल किया जाएगा। यह इंगित करता है कि प्रोग्राम इस ऑब्जेक्ट से संबंधित रनटाइम कॉन्टेक्स्ट में प्रवेश कर चुका है।
__exit__() - जब with ब्लॉक खत्म होता है तो कॉल किया जाता है। यह इंगित करता है कि प्रोग्राम इस ऑब्जेक्ट से संबंधित रनटाइम कॉन्टेक्स्ट से बाहर निकल रहा है।
फ़ाइल ऑब्जेक्ट में भी ये दो मेथड्स होते हैं जैसा कि निम्न इंटरप्रेटर सेशन से पुष्टि की जा सकती है:
>>> 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 "", line 1, in
f.write("hello world")
ValueError: I/O operation on closed file.
जब __exit__() मेथड कॉल होता है, तो फ़ाइल बंद हो जाती है। इसीलिए ValueError आता है जब हम फ़ाइल बंद होने के बाद इसमें कुछ डेटा लिखने का प्रयास करते हैं।
नीचे कॉन्टेक्स्ट मैनेजर का अधिक सामान्य उपयोग दिया गया है। पहले हम __enter__() और __exit__() मेथड्स वाली एक क्लास परिभाषित करते हैं और with स्टेटमेंट का उपयोग करके इसके ऑब्जेक्ट के लिए कॉन्टेक्स्ट मैनेजर सक्षम करते हैं।
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 डेकोरेटर होता है जिसकी मदद से हम एक जेनरेटर-आधारित फ़ैक्टरी फ़ंक्शन लिख सकते हैं जो स्वचालित रूप से with स्टेटमेंट को सपोर्ट करता है। डेकोरेटर के साथ फ़ाइल ऑब्जेक्ट का कॉन्टेक्स्ट मैनेजमेंट इस प्रकार है:
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 इस प्रकार प्रोग्राम में संसाधनों के प्रभावी प्रबंधन के लिए पायथन की एक बहुत उपयोगी विशेषता है।