this question में, मैंने एक संदर्भ प्रबंधक को परिभाषित किया जिसमें संदर्भ प्रबंधक शामिल है। इस घोंसले को पूरा करने का सबसे आसान तरीका क्या है? मैंने को self.__enter__()
पर कॉल करना समाप्त कर दिया। हालांकि, self.__exit__
में, मुझे पूरा यकीन है कि मुझे अपवाद उठाए जाने पर अंत में ब्लॉक में self.temporary_file.__exit__(type_, value, traceback)
पर कॉल करना होगा। क्या मुझे self.__exit__
में कुछ गलत होने पर टाइप_, मान और ट्रेसबैक पैरामीटर सेट करना चाहिए? मैंने contextlib
की जांच की, लेकिन इसके साथ मदद करने के लिए कोई उपयोगिता नहीं मिली।नेस्टिंग पायथन संदर्भ प्रबंधक
सवाल से मूल कोड:
import itertools as it
import tempfile
class WriteOnChangeFile:
def __init__(self, filename):
self.filename = filename
def __enter__(self):
self.temporary_file = tempfile.TemporaryFile('r+')
self.f = self.temporary_file.__enter__()
return self.f
def __exit__(self, type_, value, traceback):
try:
try:
with open(self.filename, 'r') as real_f:
self.f.seek(0)
overwrite = any(
l != real_l
for l, real_l in it.zip_longest(self.f, real_f))
except IOError:
overwrite = True
if overwrite:
with open(self.filename, 'w') as real_f:
self.f.seek(0)
for l in self.f:
real_f.write(l)
finally:
self.temporary_file.__exit__(type_, value, traceback)
यह वास्तव में अच्छा है। यदि कोई प्रश्न किसी अन्य अच्छे उत्तर उत्पन्न करता है तो मैं थोड़ी देर के लिए प्रश्न खोलने जा रहा हूं। –
'contextlib.contextmanager' का उपयोग करना सुविधाजनक है, लेकिन अभी भी ऐसे मामले हैं जहां मैन्युअल रूप से परिभाषित '__enter__' और' __exit__' विधियों के साथ कक्षा का उपयोग करना उचित है। क्या आपको ऐसा करने पर कोई सलाह है? – Zearin
ठीक है, यह अधिक सुविधाजनक होने पर करें - उदाहरण के लिए जब ऑब्जेक्ट को केवल संदर्भ प्रबंधक होने से अधिक करने की आवश्यकता होती है (हालांकि उस स्थिति में आपको @ contextlib.contextmanager विधि जोड़ने पर भी विचार करना चाहिए)। –