Context managers are used together with the with statement. You probably encountered the with statement at some point when coding in Python, the most often used case is file handling
with open('data.dat', 'r') as file: contents = file.read()
file = open('data.dat', 'r') contents = file.read() file.close()
A more robust version of dealing with a file could use the try... finally statement like this
file = open('data.dat', 'r') try: contents = file.read() finally: file.close()
The with statement has two minor advantages over the try... finally statement above: (1) it is a little bit shorter and (2) it does not require calling the close() method explicitly, since the with statement calls it automatically, whenever the program leaves the with statement (indented block below the with statement).
So the main purpose of the with statement is to guarantee the execution of startup and cleanup actions around a block of code, with the main application being resource management.
So how would we write a context manager? We can generate this functionality using a class
class MyOpen(object): def __init__(self, filename): self.filename = filename def __enter__(self): self.file = open(self.filename) return self.file def __exit__(self, ctx_type, ctx_value, ctx_traceback): self.file.close() return True
You might wonder what is the difference between __init__() and __enter__(). The __init__() method is called when the class object is created, which does not need to be the beginning of the with statement. This difference allows us to produce reusable context managers like this
file_handler = MyOpen('data.dat') with file_handler as file: contents = file.read()
So to produce a context manager you just have to create a class with two special methods: __enter__() and __exit__(). The __enter__() method returns the resource to be managed, like a file object in the case of open(). The __exit__() method does any cleanup work.
Hope that was useful and please let me know if you have any comments or questions in the comment section below.
cheers
Florian
Florian
No comments:
Post a Comment