Python's contextlib is a HIDDEN GEM

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
perhaps unsurprisingly context lib is a library dedicated to context manager Utilities in Python if you don't know what context managers are I did a video a little while ago explaining them in their raw form in this video I'm going to be using just simply the context lib to create context managers as well as show you a number of other really useful utilities I'm going to be showing you five today and hopefully by the end of this video you'll be able to use at least one of them in a program of your own of course if you find this video helpful at any point then consider leaving a like to let me know and maybe subscribe if you want to see more videos like this with all that out of the way let's get into it so the first thing that I want to show is from Context lib import context manager and you can argue that this is sort of like the flagship feature of context lib it allows you to create a context manager using just a function so it is a decorator so we can decorate it like that and if we were to create say a function or a context manager that set the random seed within a a context we would first need to import random that would help and then if we were going to type it we would need to from typing import iterator like that and then we do def seed and then I'm going to mirror uh the exact function signature of random not seed so it be a that's an INT uh float uh string bytes uh byte array or none equals none which is quite the series of options to have that's genuinely the signature and then we return an iterator in this case of none and then we're going to pass and then within this we can do random. seed a so we're actually setting the seed and then I'm going to print uh that we are yielding uh and then we just yield like that and then we print uh resetting seed and then we set the random do seed um without any arguments at all which sets it back to the default Behavior so what's happening here is well actually you know what I will do a practical example and then I'll explain it because that will probably be a bit easier to work out so if we did something like this and then if we did maybe uh two of them uh when we enter the with seed context we come up here and then we set seed and then 42 will be set to a and then we set the seed to a we then print our debug message and then we yield control of the program back into the context block so we then enter the context block here we then do everything in here we then exit the context block we come back into this and then we continue from the yield statement so we do in print resetting seed and then we'd reset the seed if we go ahead and do that we can see that we have yielding so that's here we then yield back so we then print our random values and we reset the seed afterwards if I to do that a few times we can see that the random values are the same every time if I were to print one of these actually if I just move this one out we can see that the first one is always the same but the second one is always different because we've now reset the seed because we've exited the context manager and that is well anyone that's familiar with context managers will know this is what they do but you may not have known that you can create it using a decorator and a function however our context manager is not perfect as is if we were to introduce an error inside the context block and we print it again we run it again sorry we get the yielding fine we then get the value okay and then we get the trace back but you'll notice that it never prints resetting seed and that's because we don't have any handling in place to deal with that so the general convention and pretty much I imagine what you'll see everywhere at least this is how they do it in the python Docs you'll have a try with the actual logic and this is where you put your yield and then you have a finally and then youd have your kind of cleanup operations whatever you wanted to call it and now if we do that we can see that we reset the seed and then we raise the error so context managers have their own way of handling errors um I should say that I have done a video on context managers before in their more raw form so if you're confused about what I'm talking about that I'd recommend going and watching that then coming back um but this uh context manager decorator handles all that for you and the finally block here just means that even if there is an exception within the context it will then come back in here it'll then see oh we need to run this code it'll run it reset everything and then it will go and you raise the error or whatever it wants to do if you handle the error down here so if you were to do like a try accept down here we wouldn't have that problem even if you didn't provide the finally Block it's just more you know especially if you're doing a context manager with files or databases or something and you want to make sure that something is closed then you can do that using the try finally here the other really neat feature about this context manager decorator is that you can actually use it as a decorator itself so you can use this seed as a decorator so as an example if we were to have a deaf random numbers uh here and then we provided I know Nal 3 uh or n which is an INT equals 3 by4 and then list int and then we do return random uh dot Rand int 1 to 10 and then you know n numbers of those if we were to set seed as a decorator here and we can use the same seed as before comment that out and comment that out if I just comment all that out we won't get in the way and then we can print random number numbers like that what we get back is um 215 if we do it again we will see that the random numbers are the same and that's because we've now decorated this function with a context manager so this function is sort of within the context of the context manager so for the entire duration of the execution of this function the random seed is 42 and you can see we're resetting the seed so if you would have I was going to say if we would have print it out um actually if we we can print random random we can see that the the seed has indeed been reset uh Rand in 110 we can see that second value will be different every time and that's because the seed has been reset going back to the idea of making sure that everything is closed context lib does actually provide a decorator or context manager sorry that allows you to do that I'm going to get confused to the two now that I've talked about decorators uh so we can do context lib report closing and this closing essentially uh allows you or it's it's a context manager that makes sure to close whatever has been opened in the context manager and this is largely for third-party packages that don't have context managers of their own most python interfaces do have context managers built in so the open method for example will do the URL open will do uh but you can do this on things that don't have it uh although we are going to and I will will actually take that uh I won't I'll print f. read we are going to use the open uh just for demonstration purposes to show that it works uh but you wouldn't need to do it for this you just need to be aware of it for any third party packages that you might want to do it for so if we do PI uh closing like that we can see that we printed out uh the context of the file we just wrote and we have closed the context manager now it's very difficult to prove that but I can show you what it's actually doing so when it enters it just takes the thing and then when it exits it just calls self. thing. close so anything that has a do close method will have it called when the context manager exits um and this just means that if something doesn't have a close you don't have to rely on explicitly closing it you can just use closing and it will handle it for you the third thing I want to show you is from Context l import suppress and this as the ai ai preview is showing will allow you to suppress errors uh in a way that isn't um a try accept block so typically I'll show you what you would kind of do otherwise you do try that and then that and then that and if I get rid of this so we can try one divided by 0o in the case of a zero division error we can then pass it and this will ignore or suppress the error from being raised however we can also do that using with suppress and this will suppress uh within this block if this error or any other errors I think you can pass in as many as you want yeah you can pass in as many as you want there if any of those errors show up in this block the error will be suppressed and the context block will exit so if we run this P suppress do PI we'll see that we get no output we get no Trace back because the errors have been suppressed now you can see that it takes up a lot less lines of code in my opinion it's also much more readable it's much clearer what's going on we are explicitly suppressing these errors um and sorcery the AR refracturing tool will actually recommend using suppress instead of Tri accept past that's how I learned about it but it does come with a bit of a caveat and to show that off I have this suppress Benchmark so we have our Tri accept code and we have our suppress code we then also have some timings that are running these functions a million times each so do keep that in mind when you see the results if we then run this we can see that the try accept ran in about 0.15 seconds and the suppress was three times slower so suppress is three times slower than try accept because it's just doing more work it I think it actually Compares instances and stuff which is why it's doing it if it's only ever going to be called once or twice it's probably not going to matter but if this isn't a function that's being called Millions upon Millions upon millions of times then this three times slowdown is going to start adding up so whether or not you want to use suppress will really depend on your priorities the final two things I want to show you are both very similar so we're going to talk about them at the same time and they are from Context lib import suppress nope that was last time redirect standard out and redirect standard error which do very much what they say on the tin and we're going to import CIS for something we're going to do a bit later so if we do if name equals main one final time like that uh we can with open help. txt I wish this AI would shut up it's getting really annoying right now as F we can then uh with uh redirect hand out F like that and then help pal so this example is taken straight out the python documentation what we are doing here is we are opening a file using a context manager all right clear enough as if we then redirecting the standard out to this file uh for the duration of this block so if I were to go and say like print hello world even when the file is still open we'll see that this gets printed to the terminal but if I run this we can see that hello world gets printed because it's outside of this redirection block but the help pal ends up in this file because we've redirected it and it doesn't have to be a file either it can be an I/O string object or any sort of IO object I think it can also be if you wanted to send it to CIS Dost standard error cy. standard error if you really wanted to um so basically any sort of iob based file stream you can redirect the standard out into it you can also do the same with redirect standard error now I will say that redirect standard error does not send tracebacks to a different place tracebacks are not written to standard error in Python I don't know if there's a way or maybe they are and there's some hook that just overrides it I'm not sure but if you had a program or a script or something like that that wrote anything to standard error then you can redirect that as well so we could redirect or we can open error. txt as F and then with redirect standard error say print hello world and then we'd need to send that to standard error uh and this is important actually with the standard out that I forgot to mention if you are doing a print you can redirect it using this file so this file lives by the same rules it needs to either be an open file or cy. standard error or some sort of iob based text stream in fact actually standard error is a text you can see there but if we to do that we can see that we have this error. text and then this hello world is printed here uh this second hello world on the terminal is the one from earlier you can also redirect using both so I could redirect standard out as well uh and then I could print so actually if I print uh hello standard out like that we can see that because we've redirected the standard out and the standard error to the same place our txt has both in it and you could use this to uh redirect the standard out to one place and the standard error to another I forget what python version I think it was 3.11 that allowed um opening multiple context managers at once if you're on earlier versions of python you can do this just by doing that oops he do uh and that will do the same thing let me know in the comments which feature of context lib is your favorite I think it's a really really cool tool I don't use it that much and I probably should use it a lot more because there are some really really cool functions in here especially uh the trick about creating a parameterized decorator using the context magic decorator for more tips and tricks regarding all things Python and check out the Python's awesome series in Full and I'll see you in the next video for whatever we do next
Info
Channel: Carberra
Views: 10,205
Rating: undefined out of 5
Keywords: pyfhon, pytho, pytbon, pytjon, ptyhon, pytyon, ptthon, pyyhon, pythn, pythoh, pythpn, ython, pytgon, pyhon, pytohn, phthon, oython, pthon, pyghon, pythoj, pythno, pythkn, ypthon, pytuon, lython, pyrhon, pythom, pythob, puthon, pgthon, python, pyhton, pythln, pythin, pytnon, pyton
Id: BqlKmtbMNuY
Channel Id: undefined
Length: 14min 55sec (895 seconds)
Published: Mon Jun 10 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.