Locked learning resources

Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Locked learning resources

This lesson is for members only. Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Redirecting Stdout and a File Writer

00:00 In the previous lesson, I got you started writing a custom, class-based context manager. In this lesson, I’ll show you a real usage of a context manager and then show you how to write one using the function style.

00:13 I’ll be going over two examples. In the first, I’ll show you how to redirect standard out inside of a block, and in the second, I’ll write a context manager for writing files, but this time with the function-style implementation.

00:29 Okay, let’s do something a little more useful than just saying hello. This code redirects standard out within the context block. The initializer takes a file handle where standard out will be redirected to.

00:42 .__enter__() saves the system standard out into a variable so that you can restore it later, then changes where standard out points to—in this case, the file handle from the initializer.

00:55 This .__enter__() does not return anything, so if you use the as clause, your value will be None. .__exit__() then returns standard out to its original value.

01:07 Notice that I use *args to be lazy and avoid typing exc_type, exc_value, exc_tb. And because I’m not doing anything with the exception case here, I can just ignore it all. Let’s go try this code out.

01:26 Importing …

01:37 Here I’m using the open() context manager to open a file. This is the file that I’m going to be redirecting my content to.

01:49 And this nested contact manager is my actual redirector. It takes a reference to the file and will be redirecting standout out into that file.

02:04 Printing something inside of the block … printing something outside of the block … and there’s the result. Only the second print gets output to the REPL because the first one got trapped by my redirected context manager. Let me show you the file.

02:31 And there you go. What I printed got sent the file instead. And because all of this was taken care of by the context manager, I don’t have to remember to reset standard out when I’m done playing around with it.

02:47 You can write a context manager using a function and the @contextmanager decorator instead of a class if you like. This function is a specialization of file open, explicitly for writing files. First off, you need the decorator from the contextlib module.

03:04 Then you decorate your function. And then inside of the function, everything revolves around the yield keyword. Everything before yield is the equivalent of what happens in .__enter__().

03:16 Everything after the yield is the equivalent of what happens in .__exit__(). You can yield a value, like I have here, and that is what is used as the as part of your statement, your target. And that’s it.

03:32 Context manager as a function instead of a class. It’s that simple. Let’s go try it out.

03:41 Importing … creating the context manager using "output.txt as my output file, and the target is named file

03:57 writing something to the file. And there you go. That 10 is because file.write() returns the number of bytes written. Since it’s the last line in the block, and I’m in the REPL, the REPL is showing me the value. In a script, you’d typically just ignore this result. Let’s look at the file … once again using pathlib

04:23 and there’s the content. My function-based context manager is a file-writing machine. You’ve seen all sorts of context managers—some from the standard library, and you’ve even written a few of your own.

04:37 In the last lesson, I’ll summarize the course and quickly show you a new context manager that got added in Python 3.11.

Become a Member to join the conversation.