#Python Tricks Notes
#Context Managers and the "with" statement
with open('hello.txt', 'w') as f:
f.write('hello, world')
#is the same as writing
f = open('hello.txt', 'w')
try:
f.write('hello, world')
finally:
f.close()
#the 'with' statement handles resource management
#it ensures that the file will be closed with the context
#of the statement is exited
#another example is in the threading.Lock class
import threading
some_lock = threading.Lock()
#harmful
some_lock.acquire()
try:
#do something
finally:
some_lock.release()
#better
with some_lock:
#do something
#supporting 'with' in your own objects
class ManagedFile:
def __init__(self, name):
self.name = name
def __enter__(self):
self.file = open(self.name, 'w')
return self.file
def __exit__(self, exc_type, exc_val, exc_tb):
if self.file:
self.close()
with ManagedFile('hello.txt') as f:
f.write('hello world')
f.write('bye now')
#the above shows that we can create our own context managers by using these class methods
#Snippet on context manager implementation
class Context(object):
#Object is initialized
def __init__(self, data):
self.data = data
#Enter the context
def __enter__(self):
print(f"Object {self.data} has been initialize")
#Business logic
return self.data
def __exit__(self, type, value, traceback):
#Exit
print(f"Object {self.data} has been cleaned up")
with Context("some data") as f:
print(f"Operate on data: {f}")
pass
print(f"We are now out of context")
#>>>Object some data has been initialize
#>>>Operate on data: some data
#>>>Object some data has been cleaned up
#>>>We are now out of context
#EX2: the "open" class for dealing with files has a built in context manager
#Open the file and assign variable
with open("file.json", "w") as file_:
#write some data to the file
file_.write("add data to file")
#when context is exited the manager automatically runs file_.close() on the instance