-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathContext_Managers.py
More file actions
78 lines (68 loc) · 2.63 KB
/
Copy pathContext_Managers.py
File metadata and controls
78 lines (68 loc) · 2.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# =====================================================================
# FILE: Context_Managers.py
# DESCRIPTION: Building custom context managers with classes (`__enter__`/`__exit__`) or generators (`@contextmanager`).
#
# SYNTAX QUICK-REFERENCE:
# # Class-based
# class CustomManager:
# def __enter__(self):
# return self
# def __exit__(self, exc_type, exc_val, exc_tb):
# pass
#
# # Generator-based
# from contextlib import contextmanager
# @contextmanager
# def resource():
# # setup
# yield
# # cleanup
# =====================================================================
# Context_Managers.py
# Reference Guide: Custom Context Managers using __enter__/__exit__ and contextlib module
from contextlib import contextmanager
# ==========================================
# 1. CUSTOM CLASS-BASED CONTEXT MANAGER
# ==========================================
# A class can act as a context manager by implementing __enter__() and __exit__().
print("--- 1. CLASS-BASED CONTEXT MANAGER ---")
class ManagedFile:
def __init__(self, filename, mode):
self.filename = filename
self.mode = mode
self.file = None
def __enter__(self):
print(" __enter__: Opening file")
self.file = open(self.filename, self.mode)
return self.file # The returned object is bound to the target of the 'as' clause
def __exit__(self, exc_type, exc_val, exc_tb):
print(" __exit__: Closing file")
if self.file:
self.file.close()
# Returns True to suppress exceptions if any occurred inside the block,
# or False to let them propagate (default).
return False
# Usage:
with ManagedFile("scratch_context_test.txt", "w") as f:
f.write("Hello context manager!")
print(" Inside block: Wrote to file")
import os
if os.path.exists("scratch_context_test.txt"):
os.remove("scratch_context_test.txt")
print()
# ==========================================
# 2. GENERATOR-BASED CONTEXT MANAGER (contextlib)
# ==========================================
# The @contextmanager decorator allows you to define a context manager using a generator function.
print("--- 2. GENERATOR-BASED CONTEXT MANAGER ---")
@contextmanager
def managed_resource(name):
print(f" [Setup] Allocating resource: {name}")
try:
yield f"Resource Object ({name})" # Everything before yield is setup
finally:
print(f" [Teardown] Releasing resource: {name}") # Everything after yield (in finally block) is cleanup
# Usage:
with managed_resource("API Connection") as resource:
print(f" Inside block: Working with {resource}")
print()