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

Unlock This Lesson

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

Unlock This Lesson

Hint: You can adjust the default video playback speed in your account settings.
Hint: You can set your subtitle preferences in your account settings.
Sorry! Looks like there’s an issue with video playback 🙁 This might be due to a temporary outage or because of a configuration issue with your browser. Please refer to our video player troubleshooting guide for assistance.

Files and Directories

00:00 In the previous lesson, I showed you how context managers work. In this lesson and the next, I’ll cover a few of the uses of context managers from the Python standard library.

00:10 Context managers can be found throughout the standard library and often are an alternate way of doing something. In the previous lesson, I showed opening a file in both the tryexcept way and the context manager way. In this lesson, I’m going to run you through two practical uses.

00:27 The first will give more details on opening files, and the second will show you how to use os.scandir() to iterate through the contents of a directory. In the previous lesson, I quickly spoke about reading from one file and writing to another.

00:42 Let’s take a look at some actual code that does this. On the screen is ohno.py. It takes a file name as a command-line argument, opens that file, reads each line of the file into a string, replaces all the "o"s in the string with a not sign ("🚫"), then writes the new string into a different file.

01:03 I’m using the pathlib library. It’s a more modern way of dealing with files. If you’re used to using the os module directly, you should learn about pathlib.

01:12 It’s much cleaner. On this line, I take the first command-line argument and use it to build a Path object. In a real program, I would have a bunch of error-checking here to make sure the file exists.

01:22 In this case, it’ll just be crash-tastic instead. I then create a second Path object using the same filename as the first, but adding a ".ohno" suffix to the path.

01:35 In order to report file errors, I’m wrapping my context manager in a tryexcept block. Note that this isn’t to make sure the files get closed.

01:43 The context manager will do that. This is in case the creation of the context manager throws an exception. I’ll explain more about that in a second. And here’s what you came for.

01:55 I’m instantiating two context managers from the Path object’s .open() method. This is very similar to using the built-in open() function.

02:02 The only difference is the built-in function takes the filename as an argument. With the Path object, this method calls the built-in open() function for you, passing in the filename contained in the Path object.

02:15 The first context manager here opens the src_path file and creates a file handle named src. The second opens the dest_path file and creates a file handle named dest.

02:27 The dest_path.open() uses mode "x", which is exclusive write. If the file already exists, this will throw an exception, hence why all of this is wrapped in a try block. Lines 10 through 12 do the data transformation, reading each line from the src file handle, doing the .replace() call, then writing each line into the dest file handle.

02:51 The except block prints out a message including the error that was raised, which contains the name of the file that had the problem. Let’s go try this out.

03:04 That’s my source file.

03:10 And there I’ve run the script, passing in the filename of the source file.

03:18 There’s the output, hello.txt.ohno file. Let’s try it again.

03:28 And there’s the exception. Seeing as hello.txt.ohno already exists, the dest_path.open() with argument mode="x" throws an exception.

03:42 This is a quickie using the os module’s .scandir() method. Line 5 instantiates .scandir() as a context manager, passing in the first command-line argument as a parameter.

03:54 The context manager returns a value which is stored in the entries object. I then iterate through the entries object, printing a line for each object found.

04:04 I’m showing the name of the file, padded to width 16, and its size. Let’s take a look at it.

04:16 Let me just scroll back here. This is the result for my home directory. If you’re not a Unix person, that little tilde (~) is a shortcut for home on a Unix system.

04:26 Note that some of these are directories rather than files. The 1504 bytes of music is just the metadata for the folder. It’s not the several gigs of tunes contained underneath.

04:42 Next up, two more examples of context managers in the standard library.

Become a Member to join the conversation.