# Python Tutorial: Context Managers - Efficiently Managing Resources

## Метаданные

- **Канал:** Corey Schafer
- **YouTube:** https://www.youtube.com/watch?v=-aKFBoZpiqA
- **Дата:** 20.12.2017
- **Длительность:** 20:37
- **Просмотры:** 211,353

## Описание

In this Python Programming Tutorial, we will be learning how to use context managers to properly manage resources. Context Managers are great for when we need to setup or teardown some resources during use. So these can be used for: open and closing files, opening and closing database connections, acquiring and releasing locks, and much much more. Let's get started...

The code from this video can be found at:
https://github.com/CoreyMSchafer/code_snippets/tree/master/Python-Context-Managers

Python Object-Oriented Series: https://goo.gl/ZSqx6y


✅ Support My Channel Through Patreon:
https://www.patreon.com/coreyms

✅ Become a Channel Member:
https://www.youtube.com/channel/UCCezIgC97PvUuR4_gbFUs5g/join

✅ One-Time Contribution Through PayPal:
https://goo.gl/649HFY

✅ Cryptocurrency Donations:
Bitcoin Wallet - 3MPH8oY2EAgbLVy7RBMinwcBntggi7qeG3
Ethereum Wallet - 0x151649418616068fB46C3598083817101d3bCD33
Litecoin Wallet - MPvEBY5fxGkmPQgocfJbxP6EmTo5UUXMot

✅ Corey's Public Amazon Wishlist
http://a.co/inIyro1

✅ Equipment I Use and Books I Recommend:
https://www.amazon.com/shop/coreyschafer

▶️ You Can Find Me On:
My Website - http://coreyms.com/
My Second Channel - https://www.youtube.com/c/coreymschafer
Facebook - https://www.facebook.com/CoreyMSchafer
Twitter - https://twitter.com/CoreyMSchafer
Instagram - https://www.instagram.com/coreymschafer/

#Python

## Содержание

### [0:00](https://www.youtube.com/watch?v=-aKFBoZpiqA) Introduction

hey there how's it going everybody in this video we'll be learning how to use context managers within Python so context managers allow us to properly manage resources so that we can specify exactly what we want to set up and tear down when working with certain objects so for example if anyone has ever watched my video on working with file objects then I showed two different ways that we could work with the files and the first is like we currently see up here at the top where we're opening the file and then doing something with it in this case we're just writing some text and then we have to remember to close the file after we're done working with it and also in that video I showed what I said was the recommended way of working with file objects and that is using a context manager like we have here so we can tell that this is a context manager because of the with statement here now one thing you'll notice is that we no longer have to remember to close down the file after we're done working with it and not only that but this is also recommended because if we throw an error when working with this file then it's still going to get closed properly and that is why contact managers are so useful it handles the teardown of the resources for us so that we don't have to remember to do it and the more that is handled for us automatically the better so this is great for files but it's useful for so many different resources so for example we could use this to connect to and close databases automatically we could acquire and release locks there's plenty of use cases you'll find for these you know down the road so in this video we'll be learning how to write our own context managers to handle custom resources so let's go ahead and get started so there are a couple of different ways that we can write out our own context managers we can either do this by using a class or by using a function with a decorator and we'll look at both of those in this video so to start off let's just replicate the functionality that we saw when using the context manager when opening a file so we'll create a context manager that opens the file for us and then automatically closes the file when we're done with it so first we'll use a class to create this context manager because I think it shows a little more clearly what's going on so I have a snippet in my snippets file here that we will use to get us started so you don't have to watch me type all this out so I'm just going to call this part here and paste it in I'm just gonna go ahead and overwrite that and then we will walk through this now if you're unfamiliar with working with classes and want to learn more about working with classes in Python and I do have a series specifically on that and I'll link to that in the description section below that series will explain everything that you need to know about the self parameter here and the anit method and all of that so for the sake of time I'm not really going to go into a lot of detail of the object-oriented concepts within this video okay so with that said we have a class here called open file and inside that class we have three special methods so first we have that init method which you've probably seen if you've used classes before and we also have these enter and exit methods so the inner and exit methods are going to be the setup and teardown of our context manager so we want to setup a couple of things in our NIT method so the anit method is going to accept the arguments that we pass into our class and also allow us to access the attributes that we set from our other methods so you can see here that it takes a self parameter which is just the instance itself and then we have a destination here that's not very specific I'm instead going to call this file name and also on top of file name among also going to accept a mode argument there so that file name will be the name of our file and the mode will be for opening this file for reading or writing or something like that and to turn these into instance attributes so that we can access these from our other methods we can just say self dot file name is equal to file name and then we will do the same thing for mode so self dot mode is equal to mode okay so now within our inner method which I said would be the setup part of our contact manager we're actually going to open our file so within here we can say self dot file so I'm creating a new instance variable there and now we just want to open this file so we will open self dot file name and we will open that with the mode of whatever we pass in of self dot mode and if this isn't quite making sense just yet then just stick with it and we will walk through this a couple of times so now within this inner method I'm actually going to return this file that we just created that we just opened so I'm going to return self dot file now when we return this what we return here will be the object that we're working with within our context manager okay so to finish this example up now we need to do the exit method which I said would be the teardown and this is what gets run when we exit the context manager so we want to be sure that our file gets closed at this point so we can just take this file that we created in the self dot inner method on the setup and in this hair down just do a self dot file dot close now the extra parameters here for the exit method are therefore if we throw an exception and we could use those to access that information okay so now let's use this context manager and walk through exactly what's going on so to use this we can use it just like we did before so we'll say with and I'm going to use this open file class that we just created and now this takes in a file name and the mode so I'm just going to pass in a file name of sample dot txt and we will pass this in with the mode of W which is right and then I'll say as F and then within our context manager we'll just do F dot write and we'll just write to this file and say testing and just to make sure that our context manager is working as it should and to make sure that the file was closed outside of the context manager and let's go ahead and print out the closed attribute of that file so that we can see if it was closed properly so this should return true outside of this context manager that the file was in fact closed after we were done working with it okay so if I run what we currently have then we can see that returned true for that file being closed so that's good and I have the sample dot txt file open up here if we open that up then we can see that we did write the text testing there so that all worked okay so now let's walk through the context manager and point out exactly what's going on so first of all when we run this part here with the open file class and pass in the filename and the mode what it does is it comes up here into the init method and sets those attributes so we're setting this file name and mode and then since we're using the with statement here what this does is it runs the code within our inter method so that opens the file and then that file is returned so we set this self dot file variable equal to that open file with the filename and mode and then we're returning that file variable so our f variable down here within our context manager is then set to the return value from that enter method so that is why F is a file object inside of our context manager here because that is what was returned from our enter method so now at this point with this entire line here we have ran the anit method and set those attributes and we've also run the inter method to do the setup of opening the file and returning that file and now within the context manager here we can just work with this in any way that we'd like to and then when we exit that block that is whenever and you know unand en't back here to the main part of the file that is whenever it hits the exit part of the context manager and when it runs that exit method it comes in and does the self dot file that closed so you can see that is why F dot closed return true after we have exited this context manager okay so hopefully that cleared that up on working with context managers using a class but now that we've seen how to create our own context manager using a class now let's see how to do this using a function and using a function is how I most often use context managers but that's just a personal preference so I wanted to also show the class as well so that you know both ways so to do this using a function we're going to need to use the context Lib module and to import the context manager decorator so let's go ahead and import that here at the top so we can just say from context import context manager and we can use this context manager or decorator to decorate a generator function now let me grab an example again from my snippets

### [9:03](https://www.youtube.com/watch?v=-aKFBoZpiqA&t=543s) Example

so that you don't have to watch me type all this out and then we will walk through this again now I'm just going to replace everything that we have here so far okay so we're going to go through the same example and this is the open file context manager that is equivalent to what our class was so we can see that this is a little less code than our class was but it can be a little more difficult to understand if you've never worked with decorators or generators before now just like with the classes if you'd like to learn more about decorators and generators then I do have separate videos on those topics specifically but basically if we look at our function then we can see that we have one yield statement in here where we're doing this yield F so everything before the yield statement is going to be equivalent to what our inter method of our class was so this is going to be this setup of the context manager and then the yield is actually where the code within the with statement is going to run and then everything after the yield statement is going to be equivalent to what was in the exit method of our class so this is going to be the teardown of the context manager now technically we should be using some try and finally statements in here to handle errors but we'll take a look at that in just a second but for now let's look at our sample code using this context manager and walk through it just like we did with the class and basically we're doing the same thing that we did with our class code so we're using the with statement here and calling our generator function and our function takes in a file name and a mode and then we are setting this to an F variable now at this point it's going to run everything up until our yield statement so in our example here it's going to come in and actually o create this F variable and open up that file with that file name and that mode and then it's going to yield F and yield F is just like when we returned that file within our Enter method of our class it's going to yield F and that is what this F variable here is going to equal and that is what we're going to be working with within our context manager so we can do whatever we like with this file so in our example we're just writing some more text now after we exit the with statement block then it's going to run all of the code after the yield statement so in our example that is closing our file so after the yield statement it comes up here and this is basically the teardown so just like we did before outside of our context manager we are printing F dot closed and that will tell us if the file that we opened is closed or not and since that is run in our teardown code then we should see a return value of true for that it was in fact closed okay so let's go ahead and run this code and we got an error here because whenever I typed this out this is context Lib not context Lib so context live import context manager so save that and rerun it you can see that we got a true return value for F dot closed it being true so that's good and I still have that sample dot txt file open up so if I open that then you can see that it wrote the new text so that all worked properly so one more thing when I said before that we should be using try and finally blocks to handle errors we can do that by putting our setup and yield code within a try block so if I come in here and do try and then indent this to where it is in the try block and then we're going to put the teardown code into a finally block so I'll do finally and then in that to where it is in the finally block there and doing that will ensure that even if we run into any errors our teardown code is still going to get run okay so I think that's going to do it for the open file example but that is not very practical because open is already a context manager within Python and we can already do everything that we did here just using the open function so now that we've seen how to replicate that built-in functionality of the open function that using both classes and generators now let's look at a practical example that we'll build from garage so let's say that we are using Python to do some work in a lot of different directories and we're constantly a you know seeding into those directories doing some work and then seeding back to where we started so let me grab a snippet of code here so that we can see what this would look like without a context manager so I'm going

### [13:37](https://www.youtube.com/watch?v=-aKFBoZpiqA&t=817s) Code

to copy all of this code here and paste this in let's see I will just replace all of this from scratch and we're also

### [13:49](https://www.youtube.com/watch?v=-aKFBoZpiqA&t=829s) Demo

using the OS module there so I'm going to have to also import that so I'll import OS okay so let's look at what we're trying to do here so in our code we can see that we are setting this CWD variable to our current working directory so we're just doing OS dot get current working directory and then we are changing to the directory where we want to do some work and in this case I have a let me open up my sidebar here I have two directories here I know that this is probably a little small on your screen but basically in sample directory one I have a few files and inseparable directory - so we are changing directory to sample directory one and then we are listing out everything in that directory and just printing it and then we're changing directory back to our current working directory which is our original location and you can see that we're doing this multiple times so whenever we want to do this again with sample directory - we are setting the CWD variable which is our current working directory changing directories printing out everything that is in there and then changing directories back to our original so if I

### [14:58](https://www.youtube.com/watch?v=-aKFBoZpiqA&t=898s) Review

run the code that we have now then we can see that this works so these are the files that exist in sample directory 1 and - but this is a little inconvenient to save our current directory switch directories and then switch back to the original after we're done doing what we need to do so if we look at this then saving the current directory and switching it to the destination is basically setting up for the work that needs to be done and switching back to our original directory is basically the teardown so these are things that we don't want to have to remember to do each time so this is a good candidate for a context manager so let's create one that does this so I'm going to do this with a generator function like we saw in the second example but you could also convert this to a class if you're more comfortable with that now I will create this

### [15:50](https://www.youtube.com/watch?v=-aKFBoZpiqA&t=950s) Create Function

underneath our examples here so that we have those to reference so first we're going to use the context manager decorator so I will just paste that in and now we want to create our function so I will just call this change Durr and what we're going to accept here is we want when we do our setup we are getting our current working directory and then we want to change directory to this destination so let's take in a destination as a parameter there so then within our function now remember what I said about catching errors we want to put our setup in a try and a our teardown in a finally so with our setup now we want to get that current working directory so it's just like we saw up here so we will save the current directory that we are in into that CWD favorable and now we want to change directory to our destination so I'll do an OS change directory to this destination and now we are done with our setup so now we can just yield now we are not working with any variables inside of our context manager so we don't actually have to yield anything we can just say yield so if you remember in the open file example we did a yield F where we yielded that file object and we worked with that file object with or inside of our context manager but we're not going to be working with any objects inside of our context manager so putting yield there is perfectly fine so far in our setup we have the current working directory which is our original directory we have change directory to our destination and yielded so that we're ready to do whatever we want in that destination and now in the teardown we just want to change directory back to the original so if I copy that in and paste that there then that will change directory back to that current working directory okay so now instead of

### [17:56](https://www.youtube.com/watch?v=-aKFBoZpiqA&t=1076s) Using Context Managers

doing what we did up here using this code I'm now going to use our context managers so I'm just going to delete everything that we had there and now we can use the context managers to do basically the exact same thing but a little bit more clean so we can say with changed er and now we want to pass in at the destination so our first destination we'll just do sample there one and we didn't return anything here with this yield statement so we're just instead of using as and putting a variable we're not actually working with anything there so we'll just jump directory and directly into the context manager and now from in here you can do anything within the directory that we just see deed into so in our example we were just printing out the list of that directory so OS dot list der but you could do whatever you wanted there you could create files or anything like that so now we want to do this with our sample directory too as well so I will just paste all of that in except using sample directory to there so now let's go ahead and save this and run it and I'll scroll down here a little bit so we can see that works just like it did before by printing out the contents of those directories but now we don't have to worry about the setup and teardown each time we use those contacts managers so you know before we were saving all this information and then had to remember to change back and now we can reuse this context manager over and over and we always know that those resources are going to be managed exactly how we want them to be managed and we don't have to remember to do that on our own every single time so that is a simple example of a practical context manager that you can create on your own but these are used for many different things so like I said they can be used for opening and closing database connections acquiring and releasing locks and all kinds of different stuff okay so I think that it's going to do it for this video I hope that now you have a pretty good idea for how you can use context managers to setup and teardown resources and also how you can write your own from scratch but if anyone has any questions about what we covered in this video then feel free to ask in the comment section below and I'll do my best to answer those and if you enjoy these tutorials and would like to support them then there are several ways you can do that the easiest way is to simply like the video and give it a thumbs up and also it's a huge help to share these videos with anyone who you think would find them useful and if you have the means you can contribute through patreon and there's a link to that page and it's scription section below be sure to subscribe for future videos and thank you all for watching

---
*Источник: https://ekstraktznaniy.ru/video/12434*