In the last two lessons you worked with a class-based context manager.
In this video you’ll learn how to implement a function-based context manager using Python’s contextlib module.
Function-Based Context Managers With "contextlib"
00:00
Now, I just explained to you how class-based context managers work, but this isn’t the only way to support the with statement in Python, and this is not the only way to implement a context manager.
00:13
So, there is the contextlib module in the standard library, and it provides a couple of abstractions on top of the basic context manager protocol.
00:23
And this can make your life a little easier if you’re trying to implement a use case that matches well with what the contextlib module offers.
00:32
So, here’s a quick example of what you can do with this. I’m going to re-implement the same ManagedFile functionality using the contextlib library. So, there’s a decorator in there called contextmanager and this thing is highly useful.
00:47
What that allows you to do is you can define objects that follow the context manager protocol that you can use with the with statement simply by writing a generator.
00:59
So, when looking at this code, again, you can see our familiar try and finally pattern here, where I’m acquiring the resource and then I’m yielding it, and then later, I’m closing the resource.
01:12
And what happens is that this @contextmanager decorator will turn this generator function—or, this generator that I just defined here—it will turn that into a full-blown context manager that I can use with the with statement. So again, I can do something like this.
01:32
I can say with managed_file('hello.txt')—
01:40
I’m just going to call it f again. I can say, “Write something to the file,” and of course we can also write more stuff to the same file. And now, when I run this, we’re actually writing to the file.
01:52
If you’re wondering what this is—so, this is just the number of characters written, because .write() returns how many characters were written to the file, right?
01:59 It’s just kind of leaking back into my interpreter session here.
Dan Bader RP Team on May 9, 2019
I can’t get why a generator is needed.. Could you clarify that please?
Ah, the reason is that contextlib.contextmanager requires a generator :) Using a generator allows the function to be temporarily “paused” and then later resumed again for the context manager’s “exit” step. A regular function can’t do that sort of thing, hence the yield to define a generator.
Become a Member to join the conversation.

Gilles Consulting on May 9, 2019
Hello, Thanks for you videos. very clear, even if for this one I have 2 questions:
I am wondering why you defined a generator, with a
yield, instead of areturn. well, it does not work with areturn:) I can’t get why a generator is needed.. Could you clarify that please?Also, if I understand properly, in you managed_file function the “try:” is taken in charge by the
__enter__function, and the finally by the__exit__one (cf the class you defined in your previous video to reproduce thewithbehavior. Could you confirm if it’s correct?Thank you in advance.