Do you know how the washing machine works?
Ok. So what we do
- Start the machine
- Select the mode in which we want to wash our clothes
We did not have to wait to stop the machine, it would stop automatically. However, if it was not automatic, we need to stop it manually. It's not tough to stop the machine manually, But what if you got busy at work and forgot!!! What do you think will happen?
Let's not think about the condition of clothes!
The same happens in programming, assume that we want to write on a file so it goes like this
f = open('filename.txt', 'w') f.write("I am Washing clothes hahahaha!!!") f.close()
You can see in the above program we have opened a file to write and then we needed to manually close it but if like the washing machine we forgot to do it.
If the file stays open, it gets locked for other resources to use it, until the process closes it itself and when you open the file again you will not see the changes you made. So like the automatic washing machine, here the context manager does it all. In the above program, we can use the context manager called
with so that our file gets automatically closed.
with open('file_name.txt', 'w') as f: f.write('I am going to close automatically hahahaha!!!')
The above code will open a file, write the data and then close it, if any error occurs while writing the data, even then it will close the file.
Let's look at what a context manager really is.
What is a Context Manager?
Context manager helps you allocate and release resources. It creates a temporary context for you and deletes it later, for example in a hotel when you check-in, the room gets yours, but temporarily and as soon as you check-out, housekeeping cleans it fully as if you never stayed there. A hotel manager is like the context manager in Python who sees your room allocation and check-out details to make the room available for another guest.
Context manager releases the resources so there is availability and no resource leakage, so that our system does not slow down or crash. The best example of a context manager is
with statement that we discussed above.
Context Manager as Class
class open_file(): def __init__(self, file_name, mode): self.file_name = file_name self.mode = mode def __enter__(self): self.file=open(self.file_name,self.mode) return self.file def __exit__(self, err_type, err_value, err_traceback): self.file.close()
We created a context manager class that has three functions
__init__: this will execute as soon as you create the object of class. It has two parameters filename and mode in which it is opened .
__enter__: after init it will go to the entered function
__exit__: as soon as we go out of the block this function will execute. It has three parameters which are used when we get any error and want to find details about it.
with open_file('file_name.txt', 'w') as f: f.write('Context_Manager class is working')
- So what happens when we write
open_file('file_name.txt', 'w'), it goes to
__init__method and sets the attribute.
- Since we are using the
withstatement, it execute our
__enter__method, which opens the file and returns it.
- So our f variable is set to have the return value from the
__enter__method that is why f is the file object in our context manager because in
__enter__method we have returned
- Now it will execute the statements we have written inside the block.
- So as soon as we get out of the block
__exit__method and execute it.
Now as we were writing on file we get an error so how the error will be handled? In the
__exit__ method, we mentioned
err_traceback these are the parameters that the exit method will use to handle the error. If any error occurs in our program, it will return
with statement will raise the exception.
If the exit method returns
True then the
with statement will not raise any exception as True means the error has been handled.
So, let's try to handle the error
class open_file(): def __init__(self, file_name, mode): self.file_name = file_name self.mode = mode def __enter__(self): self.file=open(self.file_name,self.mode) return self.file def __exit__(self, err_type, err_value, err_traceback): print("Error has been handled") #optional self.file.close() return True
Context Manager as Generator
contextliblibrary. So that we can use this
contextmanagerdecorator to decorate our generator function.
from contextlib import contextmanager @contextmanager def open_file(file_name,mode): f = open(file_name,mode) try: yield f except Exception: print("Error has been handled") finally: f.close() with open_file('file_name.txt', 'w') as f: f.write('Context_Manager class is working')
You can think and understand the code like this,
- The code before
yield, is like your
__enter__method in class
Yieldis the code inside the
- The code after yield is like the
So if you will get any error, it will be handled by the except block and the file will get closed every time, doesn't matter if we get an error or not as the
finally block can execute with or without error.
Hope, you got the understanding of Context Manager