निम्नलिखित को धयान मे रखते हुए:
with open(path, mode) as f:
return [line for line in f if condition]
क्या फ़ाइल ठीक से बंद हो जाएगी, या return
किसी भी तरह से संदर्भ प्रबंधक को बायपास कर देगा ?
निम्नलिखित को धयान मे रखते हुए:
with open(path, mode) as f:
return [line for line in f if condition]
क्या फ़ाइल ठीक से बंद हो जाएगी, या return
किसी भी तरह से संदर्भ प्रबंधक को बायपास कर देगा ?
जवाबों:
हां, यह finally
एक ब्लॉक के बाद ब्लॉक की तरह कार्य करता है try
, अर्थात यह हमेशा निष्पादित होता है (जब तक कि अजगर प्रक्रिया असामान्य तरीके से समाप्त नहीं हो जाती)।
यह पीईपी -343 के उदाहरणों में से एक में भी वर्णित है जो कि विवरण के लिए विनिर्देश है with
:
with locked(myLock):
# Code here executes with myLock held. The lock is
# guaranteed to be released when the block is left (even
# if via return or by an uncaught exception).
हालांकि, कुछ ध्यान देने योग्य बात यह है कि आप open()
पूरे with
ब्लॉक को ब्लॉक के अंदर रखे बिना कॉल द्वारा फेंके गए अपवादों को आसानी से नहीं पकड़ सकते हैं, try..except
जो आमतौर पर कोई भी नहीं चाहता है।
Process.terminate()
में से कुछ (एकमात्र) परिदृश्य में से एक है जो एक finally
बयान की कॉल की गारंटी नहीं देता है : "ध्यान दें कि बाहर निकलने वाले हैंडलर और अंत में क्लॉज़ इत्यादि नहीं होंगे। मार डाला। "
with
ब्लॉक के भीतर से एक जनरेटर अभिव्यक्ति लौटाता हूं , तो जब तक जनरेटर मूल्यों को बनाए रखता है, तब तक क्या गारंटी है? जब तक कुछ भी इसे संदर्भित करता है? I क्या del
जनरेटर ऑब्जेक्ट को रखने वाले वैरिएबल को एक अलग मूल्य का उपयोग या असाइन करने की आवश्यकता है ?
ValueError: I/O operation on closed file.
:।
हाँ।
def example(path, mode):
with open(path, mode) as f:
return [line for line in f if condition]
.. यह बहुत अधिक के बराबर है:
def example(path, mode):
f = open(path, mode)
try:
return [line for line in f if condition]
finally:
f.close()
अधिक सटीक रूप से, __exit__
एक संदर्भ प्रबंधक में विधि को हमेशा ब्लॉक से बाहर निकलते समय (अपवादों, रिटर्न आदि की परवाह किए बिना) कहा जाता है। फ़ाइल ऑब्जेक्ट का __exit__
तरीका सिर्फ कॉल करता है f.close()
(जैसे कि CPython में )
finally
keywrod है: def test(): try: return True; finally: return False
।
हाँ। आम तौर पर, __exit__
एक संदर्भ कथन संदर्भ प्रबंधक की विधि को वास्तव return
में संदर्भ के अंदर से घटना में कहा जाएगा । यह निम्नलिखित के साथ परीक्षण किया जा सकता है:
class MyResource:
def __enter__(self):
print('Entering context.')
return self
def __exit__(self, *exc):
print('EXITING context.')
def fun():
with MyResource():
print('Returning inside with-statement.')
return
print('Returning outside with-statement.')
fun()
आउटपुट है:
Entering context.
Returning inside with-statement.
EXITING context.
उपरोक्त आउटपुट पुष्टि करता है कि __exit__
शुरुआती के बावजूद बुलाया गया था return
। जैसे, संदर्भ प्रबंधक को दरकिनार नहीं किया जाता है।
हां, लेकिन अन्य मामलों में कुछ दुष्प्रभाव हो सकते हैं, क्योंकि यह __exit__
ब्लॉक में कुछ (जैसे फ्लशिंग बफर) करना चाहिए
import gzip
import io
def test(data):
out = io.BytesIO()
with gzip.GzipFile(fileobj=out, mode="wb") as f:
f.write(data)
return out.getvalue()
def test1(data):
out = io.BytesIO()
with gzip.GzipFile(fileobj=out, mode="wb") as f:
f.write(data)
return out.getvalue()
print(test(b"test"), test1(b"test"))
# b'\x1f\x8b\x08\x00\x95\x1b\xb3[\x02\xff' b'\x1f\x8b\x08\x00\x95\x1b\xb3[\x02\xff+I-.\x01\x00\x0c~\x7f\xd8\x04\x00\x00\x00'
else
with
उसtry with except
समस्या को हल करने के लिए जोड़ा जा सकता है। संपादित करें: भाषा में जोड़ा गया