নিম্নোক্ত বিবেচনা কর:
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
, যেমন এটি সর্বদা চালিত হয় (যদি না অজগর প্রক্রিয়াটি একটি অস্বাভাবিক পদ্ধতিতে শেষ হয়)।
এটি PEP-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
বিবৃতি দেয়ার নিশ্চয়তা দেয় না : "নোট করুন যে প্রস্থান হ্যান্ডলার এবং শেষ অবধি, ইত্যাদিগুলি হবে না নিষ্পন্ন."
os._exit
মাঝে মাঝে ব্যবহৃত হয় - এটি ক্লিনআপ হ্যান্ডলারদের কল না করে পাইথন প্রক্রিয়াটি থেকে বেরিয়ে যায়।
with
ব্লকের মধ্যে থেকে কোনও জেনারেটর এক্সপ্রেশন ফিরে পাই তবে জেনারেটর যতক্ষণ ধরে মান দেয় না তার গ্যারান্টিটি কী ধরে রাখতে পারে? কোন কিছুর জন্য এটি রেফারেন্স হিসাবে? অর্থাৎ 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()
(যেমন সিপিথনে এখানে )
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
সমস্যাটি সমাধান করতে যোগ করা যেতে পারে । সম্পাদনা: ভাষায় যুক্ত হয়েছে