खोज…


परिचय

जबकि पायथन के संदर्भ प्रबंधक व्यापक रूप से उपयोग किए जाते हैं, कुछ लोग उनके उपयोग के पीछे के उद्देश्य को समझते हैं। आमतौर पर फ़ाइलों को पढ़ने और लिखने के साथ उपयोग किए जाने वाले ये कथन सिस्टम मेमोरी को संरक्षित करने में एप्लिकेशन की सहायता करते हैं और कुछ प्रक्रियाओं के लिए केवल विशिष्ट संसाधनों का उपयोग करके संसाधन प्रबंधन में सुधार करते हैं। यह विषय पायथन के संदर्भ प्रबंधकों के उपयोग की व्याख्या और प्रदर्शन करता है।

वाक्य - विन्यास

  • "Reference_manager" ("उपनाम" के रूप में) (, "reference_manager" ("उपनाम") के रूप में?):?

टिप्पणियों

संदर्भ प्रबंधक पीईपी 343 में परिभाषित किए गए हैं। वे try ... finally तुलना में संसाधन प्रबंधन के लिए अधिक रसीला तंत्र के रूप में उपयोग किए जाने का इरादा रखते हैं try ... finally निर्माण करते हैं। औपचारिक परिभाषा इस प्रकार है।

इस PEP में, संदर्भ प्रबंधक __enter__() और __exit__() विधियां प्रदान करते हैं जो कि प्रवेश के साथ और कथन के शरीर से बाहर निकलने पर आह्वान किया जाता है।

यह तो परिभाषित करने के लिए पर चला जाता है with इस प्रकार के बयान।

with EXPR as VAR:
    BLOCK

उपरोक्त कथन का अनुवाद है:

   mgr = (EXPR)
   exit = type(mgr).__exit__  # Not calling it yet
   value = type(mgr).__enter__(mgr)
   exc = True
   try:
       try:
           VAR = value  # Only if "as VAR" is present
           BLOCK
       except:
           # The exceptional case is handled here
           exc = False
           if not exit(mgr, *sys.exc_info()):
               raise
           # The exception is swallowed if exit() returns true
   finally:
       # The normal and non-local-goto cases are handled here
       if exc:
           exit(mgr, None, None, None)

संदर्भ प्रबंधकों का परिचय और कथन के साथ

एक संदर्भ प्रबंधक एक वस्तु है जिसे एक संदर्भ (कोड का एक ब्लॉक) शुरू होने और समाप्त होने पर अधिसूचित किया जाता है । आप आमतौर पर कथन के with एक का उपयोग करते हैं। यह ध्यान देने योग्य है।

उदाहरण के लिए, फ़ाइल ऑब्जेक्ट संदर्भ प्रबंधक हैं। जब कोई संदर्भ समाप्त होता है, तो फ़ाइल ऑब्जेक्ट स्वचालित रूप से बंद हो जाता है:

open_file = open(filename)
with open_file:
    file_contents = open_file.read()

# the open_file object has automatically been closed.

ऊपर दिए गए उदाहरण को आमतौर पर कीवर्ड के as उपयोग करके सरल किया as :

with open(filename) as open_file:
    file_contents = open_file.read()

# the open_file object has automatically been closed.

कुछ भी जो ब्लॉक के निष्पादन को समाप्त करता है, संदर्भ प्रबंधक के निकास विधि को कहा जाता है। इसमें अपवाद शामिल हैं, और तब उपयोगी हो सकता है जब कोई त्रुटि आपको एक खुली फ़ाइल या कनेक्शन से समय से पहले निकलने का कारण बनती है। फ़ाइलों / कनेक्शनों को ठीक से बंद किए बिना स्क्रिप्ट से बाहर निकलना एक बुरा विचार है, जिससे डेटा हानि या अन्य समस्याएं हो सकती हैं। एक संदर्भ प्रबंधक का उपयोग करके आप यह सुनिश्चित कर सकते हैं कि इस तरह से नुकसान या हानि को रोकने के लिए हमेशा सावधानी बरती जाती है। पायथन 2.5 में यह फीचर जोड़ा गया था।

किसी लक्ष्य को सौंपना

कई संदर्भ प्रबंधक दर्ज किए जाने पर एक वस्तु लौटाते हैं। आप उस वस्तु को नए नाम के with स्टेटमेंट में असाइन कर सकते हैं।

उदाहरण के लिए, एक में एक डेटाबेस कनेक्शन का उपयोग कर with बयान आप एक कर्सर वस्तु दे सकता है:

with database_connection as cursor:
    cursor.execute(sql_query)

फ़ाइल ऑब्जेक्ट्स स्वयं लौटते हैं, इससे फ़ाइल ऑब्जेक्ट को खोलना और इसे एक संदर्भ में संदर्भ प्रबंधक के रूप में उपयोग करना संभव हो जाता है:

with open(filename) as open_file:
    file_contents = open_file.read()

अपना खुद का संदर्भ प्रबंधक लिखना

एक संदर्भ प्रबंधक कोई भी वस्तु है जो दो जादू विधियों __enter__() और __exit__() को लागू करता है (हालांकि यह अन्य तरीकों को भी लागू कर सकता है):

class AContextManager():

    def __enter__(self):
        print("Entered")
        # optionally return an object
        return "A-instance"

    def __exit__(self, exc_type, exc_value, traceback):
        print("Exited" + (" (with an exception)" if exc_type else ""))
        # return True if you want to suppress the exception

यदि संदर्भ अपवाद से बाहर निकलता है, तो उस अपवाद के बारे में जानकारी ट्रिपल exc_type , exc_value , traceback रूप में पारित हो जाएगी (ये वही वैरिएबल हैं जैसे कि sys.exc_info() फ़ंक्शन द्वारा लौटाए गए हैं)। यदि संदर्भ सामान्य रूप से बाहर निकलता है, तो इन तीनों में से None तर्क None होगा।

यदि कोई अपवाद होता है और __exit__ विधि से पारित किया जाता है, तो अपवाद को दबाने के लिए विधि True तरीके से वापस आ सकती है, या अपवाद __exit__ फ़ंक्शन के अंत में फिर से उठाया जाएगा।

with AContextManager() as a:
    print("a is %r" % a)
# Entered
# a is 'A-instance'
# Exited

with AContextManager() as a:
    print("a is %d" % a)
# Entered
# Exited (with an exception)
# Traceback (most recent call last):
#   File "<stdin>", line 2, in <module>
# TypeError: %d format: a number is required, not str

ध्यान दें कि दूसरे उदाहरण में भले ही एक बयान के साथ शरीर के बीच में अपवाद हो, __exit__ हैंडलर को अभी भी निष्पादित किया जाता है, इससे पहले कि अपवाद बाहरी दायरे में फैलता है।

यदि आपको केवल __exit__ विधि की आवश्यकता है, तो आप संदर्भ प्रबंधक का उदाहरण वापस कर सकते हैं:

class MyContextManager:
    def __enter__(self):
        return self

    def __exit__(self):
        print('something')

जनरेटर सिंटैक्स का उपयोग करके अपना स्वयं का संदर्भ लिखना

यह भी संभव है करने के लिए जनरेटर वाक्य रचना धन्यवाद का उपयोग कर एक संदर्भ प्रबंधक लिखने के contextlib.contextmanager डेकोरेटर:

import contextlib

@contextlib.contextmanager
def context_manager(num):
    print('Enter')
    yield num + 1
    print('Exit')

with context_manager(2) as cm:
    # the following instructions are run when the 'yield' point of the context
    # manager is reached.
    # 'cm' will have the value that was yielded
    print('Right in the middle with cm = {}'.format(cm))

पैदा करता है:

Enter
Right in the middle with cm = 3
Exit

डेकोरेटर जनरेटर को एक में परिवर्तित करके एक संदर्भ प्रबंधक लिखने का कार्य सरल करता है। उपज अभिव्यक्ति से पहले सब कुछ __enter__ विधि बन जाता है, उपज का मूल्य जनरेटर द्वारा लौटाया गया मान बन जाता है (जो कि कथन के साथ एक चर के लिए बाध्य हो सकता है), और उपज अभिव्यक्ति के बाद सब कुछ __exit__ विधि बन जाता है।

एक अपवाद की जरूरत संदर्भ प्रबंधक द्वारा नियंत्रित किया जा करने के लिए करते हैं, तो एक try..except..finally -block जनरेटर में लिखा जा सकता है और किसी भी अपवाद में उठाया with -block इस अपवाद ब्लॉक द्वारा नियंत्रित किया जाएगा।

@contextlib.contextmanager
def error_handling_context_manager(num):
    print("Enter")
    try:
        yield num + 1
    except ZeroDivisionError:
        print("Caught error")
    finally:
        print("Cleaning up")
    print("Exit")

with error_handling_context_manager(-1) as cm:
    print("Dividing by cm = {}".format(cm))
    print(2 / cm)

यह उत्पादन करता है:

Enter
Dividing by cm = 0
Caught error
Cleaning up
Exit

एकाधिक संदर्भ प्रबंधक

आप एक ही समय में कई सामग्री प्रबंधक खोल सकते हैं:

with open(input_path) as input_file, open(output_path, 'w') as output_file:

    # do something with both files. 
    
    # e.g. copy the contents of input_file into output_file
    for line in input_file:
        output_file.write(line + '\n')

यह घोंसले के शिकार प्रबंधकों के रूप में एक ही प्रभाव है:

with open(input_path) as input_file:
    with open(output_path, 'w') as output_file:
        for line in input_file:
            output_file.write(line + '\n')

संसाधन प्रबंधित करें

class File():
    def __init__(self, filename, mode):
        self.filename = filename
        self.mode = mode

    def __enter__(self):
        self.open_file = open(self.filename, self.mode)
        return self.open_file

    def __exit__(self, *args):
        self.open_file.close()

__init__() विधि ऑब्जेक्ट सेट करती है, इस मामले में फ़ाइल का नाम और फ़ाइल खोलने के लिए मोड सेट करना है। __enter__() फ़ाइल को खोलता है और लौटाता है और __exit__() बस इसे बंद कर देता है।

इन जादू विधियों (का उपयोग करते हुए __enter__ , __exit__ ) आप वस्तुओं जो आसानी से इस्तेमाल किया जा सकता लागू करने के लिए अनुमति देता है with बयान के साथ।

फ़ाइल वर्ग का उपयोग करें:

for _ in range(10000):
    with File('foo.txt', 'w') as f:
        f.write('foo')


Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow