After writing your first own context manager, you’ll walk through the process, which is executed when using a context manager.
How Context Managers Work, Step by Step
All right, so I want to talk a little bit more about the steps that Python takes behind the scenes for this example to actually work. You can see here, we defined this
ManagedFile class, and we’ve got this constructor here that just assigns the
name, it remembers the
name from the file that we want to create.
So that, really, the resource gets acquired when the
.__enter__() method is called and it gets released when the
.__exit__() method is called. And then the
.__exit__() method also takes additional parameters that will tell you about some exception that might’ve happened, in case you want to inspect that, log that, or do something with that.
I’m not doing that here—I’m just checking like, “Hey, did we actually open anything?” If so, then we’re going to close the file. And now, obviously, with this example you need to remember that this is sort of a useless wrapper around the
open() function here, because the
open() function already pretty much does that when it functions as a context manager, right? So this is merely an example to illustrate that, but you could imagine this would be some other kind of resource, like a database connection. So now, what’s going on here in this example?
Because when we create an instance of
ManagedFile, we’re not actually immediately calling the
.__enter__() method. So I could also do something like this—I’m going to call this
mf, which is not an ideal name, but for this example
we didn’t actually call the
.__enter__() method, right? You can see that here with this exception, because the object doesn’t have a
.file attribute yet—we didn’t assign that yet, because we didn’t call
.__enter__() yet—or, Python didn’t call
.__enter__() yet. Now, when I go ahead and do
with mf, and then I can say something like
with mf as the_file,
So, what you can see here with this statement,
with mf as the_file—behind the scenes this is going to call
.__enter__(), and then it’s going to assign the return value—so, this is going to return the actual file—
Because this was the actual file object that I needed to write to the file. Then, when we leave the context—like, right after I’m making this call here—we’re going back one indentation level, we’re leaving this context. Then immediately Python is going to call the
.__exit__() method, or the dunder exit method.
Become a Member to join the conversation.