🎁
File Handling

with Statement (Context Managers)

Automatic Cleanup
💡 with statement C++ ke RAII jaisa hai — resource acquire karo aur GUARANTEE milta hai ki release hoga, chahe kuch bhi ho (exception aaye ya na aaye), bina manually close() yaad rakhe.

with statement Python ka "context manager" protocol use karta hai — with open(...) as f: block ke andar file automatically open rehti hai, block khatam hote hi (normally ya exception se) automatically close() ho jaati hai. Ye RAII pattern ka Python equivalent hai.

Apni khud ki classes ko bhi context-manager-compatible bana sakte ho — __enter__ aur __exit__ dunder methods implement karke. __exit__ guaranteed chalta hai, chahe block mein exception aaye.

# Modern, recommended way:
with open("data.txt", "r") as f:
    content = f.read()
    print(content)
# yahin automatically f.close() ho jaata hai — chahe exception aaye ya na aaye!

# Custom context manager:
class Timer:
    def __enter__(self):
        import time
        self.start = time.time()
        return self
    def __exit__(self, exc_type, exc_val, exc_tb):
        import time
        print(f"Time taken: {time.time() - self.start:.4f}s")

with Timer():
    total = sum(range(1000000))   # kaam karo
# automatically time print ho jaata hai block khatam hote hi
🎁
with statement C++ ke RAII jaisa hai — resource acquire karo aur GUARANTEE milta hai ki release hoga, chahe kuch bhi ho (exception aaye ya na aaye), bina manually close() yaad rakhe.
1 / 2
⚡ झट से Recap
  • with open(...) as f: — automatic close(), chahe exception aaye
  • __enter__/__exit__ = custom context managers banane ke liye
  • Python ka RAII jaisa pattern — resource safety
इस page में (2 subtopics)

Poori class (__enter__/__exit__) likhne ke bajaye, @contextmanager decorator se generator function se bhi context manager bana sakte ho — chhote cases ke liye simpler.

from contextlib import contextmanager
import time

@contextmanager
def timer():
    start = time.time()
    yield              # yahi "with" block ka code chalta hai
    print(f"Time: {time.time() - start:.4f}s")

with timer():
    total = sum(range(1000000))
# automatically time print hota hai
💡Tip: yield se pehle ka code __enter__ jaisa hai, yield ke baad ka code __exit__ jaisa hai — bahut concise pattern jab full class-based approach overkill lage.

Ek with statement mein multiple context managers comma se separate karke ek saath use kar sakte ho — jaise ek file se padhna aur doosri mein likhna, dono automatically close honge.

with open("input.txt", "r") as infile, open("output.txt", "w") as outfile:
    for line in infile:
        outfile.write(line.upper())
# dono files automatically close ho jaati hain block khatam hote hi
💡Tip: Ye pattern (multiple resources ek saath) bahut common hai data-processing scripts mein — ek file se read karke doosri mein transform karke likhna.