संदर्भ प्रबंधक वैकल्पिक रूप सेas
नामक पहचानकर्ता को असाइन करने के लिए एक ऑब्जेक्ट लौटा सकता है। और यह __enter__
विधि द्वारा लौटाई गई वस्तु है जिसे as
द्वारा असाइन किया गया है, जरूरी नहीं कि संदर्भ प्रबंधक स्वयं ही हो।
as <identifier>
का उपयोग करने में मदद करता है जब आप एक नई वस्तु बनाने, open()
कॉल की तरह करता है, लेकिन सभी संदर्भ प्रबंधकों सिर्फ संदर्भ के लिए बनाई गई हैं। वे पुन: प्रयोज्य हो सकते हैं और उदाहरण के लिए पहले से ही बनाए जा चुके हैं।
डेटाबेस कनेक्शन लें। आप केवल एक बार डेटाबेस कनेक्शन बनाते हैं, लेकिन कई डेटाबेस एडेप्टर आपको संदर्भ प्रबंधक के रूप में कनेक्शन का उपयोग करने देते हैं; संदर्भ दर्ज करें और लेन-देन शुरू कर दिया है, यह से बाहर निकलें और लेन-देन (सफलता पर) या तो प्रतिबद्ध है, या वापस लुढ़का (जब वहाँ एक अपवाद है):
with db_connection:
# do something to the database
कोई नई वस्तुओं यहाँ, बनाया जा करने की जरूरत है संदर्भ db_connection.__enter__()
के साथ दर्ज किया गया है और db_connection.__exit__()
के साथ फिर से बाहर निकला है, लेकिन हम पहले से ही कनेक्शन ऑब्जेक्ट का संदर्भ रखते हैं।
अब, यह हो सकता है कि कनेक्शन ऑब्जेक्ट दर्ज करते समय कर्सर ऑब्जेक्ट उत्पन्न करता है। अब यह समझ में आता है एक स्थानीय नाम पर है कि कर्सर वस्तु आवंटित करने के लिए:
with db_connection as cursor:
# use cursor to make changes to the database
db_connection
अभी भी यहाँ बुलाया गया था नहीं, यह पहले से ही से पहले मौजूद है, और हम पहले से ही यह करने के लिए एक संदर्भ है। लेकिन जो भी db_connection.__enter__()
उत्पादित किया गया है अब cursor
को सौंपा गया है और इसका उपयोग वहां से किया जा सकता है।
यह फाइल ऑब्जेक्ट्स के साथ होता है; open()
एक फ़ाइल वस्तु देता है, और fileobject.__enter__()
फ़ाइल वस्तु ही देता है, ताकि आप एक with
बयान में open()
कॉल उपयोग कर सकते हैं और एक कदम में नव निर्मित वस्तु के लिए एक संदर्भ असाइन करते हैं, बल्कि दो से।उस छोटी सी चाल के बिना, आपको इसका उपयोग करना होगा:
f = open('myfile.txt')
with f:
# use `f` in the block
यह सब आपके शेडर उदाहरण पर लागू करना; आपके पास पहले से ही self.shader
का संदर्भ है। यह काफी संभावना है कि self.shader.__enter__()
फिर से self.shader
का संदर्भ देता है, लेकिन चूंकि आपके पास पहले से ही एक पूरी तरह से सेवा योग्य संदर्भ है, तो इसके लिए एक नया स्थानीय क्यों बनाएं?
यदि आपको 'साथ' ब्लॉक के अंदर संदर्भ प्रबंधक को उपनाम करने की आवश्यकता नहीं है, तो यह ठीक है - उदाहरण भी देखें [ 'Contextlib.suppress'] (https://docs.python.org/3.4/library/contextlib.html#contextlib.suppress)। कड़ाई से, आप खुले (...): ... 'के साथ कर सकते हैं, हालांकि, जब आप फ़ाइल हैंडलर तक नहीं पहुंच सकते हैं तो बहुत कुछ नहीं है! – jonrsharpe