Resources
Summary
What's Context Manager?
A context manager is a concept that enables us to perform predefined actions both before and after our main action. We use them using with keyword.
You've probably used context managers before for opening files like that👇.
This open context-manager ensures that file is closed after the code block. This is crucial to not corrupt files when you work in the 'write' mode with any files.
We can create similar context-manager, that will Start and Commit our Transaction. And on top of that we will add try/except statements and optionally print error message.
How to Create Context Manager?
There are 2 ways to create a context manager.
1️⃣ We can create a generator function and apply a special decorator for that function, so python recognizes it as a context manager.
2️⃣ Or we can create a Class and use its __enter__ and __exit__ methods.
💡 I prefer using functions if context manager is simple enough, and use Class if I need a lot of functionality.
Let's look how to create them.
Create Context Manager with Function
To create context manager with a function we need to import contextlib module and use context-manager decorator. This will indicate python that our generator function will be used as a context-manager.
💡Generator functions use yield instead of return.
If we apply context-manager decorator, then we can define code Before and After yield statement. And our code in with statement will be placed instead of yield.
👇It might sound confusing but have a look at this template for context-manager:
👆 That's the base template you can use.
I only made print statements 'Before'/'After', but you can put any code instead to be executed before or after the yield part.
yield part is going to replaced with any code we write under 'with ef_Transaction:'
👇 Here is an example:
So using this context-manager will give you results like the following code.
We have our print statements Before and After, and our code will be placed instead of yield statement.
Transaction Context-Manager
So in our case we would want to Create a Transaction and then Start and Commit it before and after. We also need to provide arguments for creating our transaction such as doc and title.
👇Here is simple context-manager that will do that.
👀 Let's also add try/except statements and an argument to optionally print an error message.
Now this context-manager will take care of Starting and Committing a Transaction. We also have integrated try/except statement with an option to print error messages if any.
Now if we want to use it to create a random Wall, we can use the following Snippet.
By using this, we don't need to use Start, Commit and Try/Except anymore. It's already included in our context-manager.
💡And you can add as much logic as you want to make it even more powerful!
Create Try/Except Context-Manager
Let's also create another context-manager to make try/except statements more compact. I saw some codes where people used more than 10+ of them, and except was everywhere just pass. So there were a lot of useless liens of code.
💡 Let's make them more readable and reusable!
We can just remove Transaction part from previous code, and we will have our try/except context-manager.
So when you use it, it will look like this in comparison:
💡 These are only 2 statements. Imagine the difference if we would have 10+ of them.
Create Context Manager with Class
So you've learnt how to create context-manager by using generator function with a decorator. Now let's recreate the same context-manager for Transaction but using Class this time.
We would create a class as usual, and provide arguments in __init__ method.
And then we can use the following methods for making it as a context-manager.
__enter__(self)__exit__
(self, exc_type, exc_value, traceback)
💡Don't forget to use required arguments for __exit__ method!
👆 So now this context-manager made with a Class is exact copy of the one we made with a generator function. Give it a try.
🎯 And it's exactly the same to use it.
Reuse your Custom Context-Manager
👀 Are you a great programmer who reuses code?
If yes, then don't forget to place one of the context-manager to your lib, so you can start using it in your future tools!
Just place the code and all necessary imports in lib/Snippets/_context_managers.py and enjoy a better way to handle Transactions.
Conclusion
Overall, it's not a complicated concept, but it might be tricky to explain it in a written format. So make sure you watch the video to better understand how it works!
It might be a little confusing if you see it for the first time. But, I think once you create and use your own custom context-manager something will click and you will suddenly understand it!
Final Code
lib/Snippets/_context_managers.py
HomeWork
👀 There were many examples, so give some of them a try!
💡 I would also recommend to make changes and see what happens. Try to add print statements in different places, and see what you get!
✅ Don't forget to recreate it in your lib to reuse it.