Context Managers just make the code a little prettier, they're ground breaking

Purpose: Allocate and release resources precisely when you want to. In some cases they can also be used to set and reset settings immediately after leaving the code block. Those context managers are usually supported and provided by a library. Examples include: {python}torch.no_grad() or {python}pd.option_context("display.max_rows", None)

with open("filepath", "w") as f:
	f.write("Hey!")

The file gets automatically closed, no need to specify it. It is equivalent to:

f = open("filepath", "w")
try:
	f.write("Hey!")
finally:
	f.close()

Implement my own context manager:

class File(object):
    def __init__(self, file_name, method):
        self.file_obj = open(file_name, method)
    def __enter__(self):
        return self.file_obj
    def __exit__(self, type, value, traceback):
        self.file_obj.close()

calling it

with File('demo.txt', 'w') as opened_file:
    opened_file.write('Hola!')

How it works is kinda self explanatory.