Opening and Closing Files

In this lesson, you’ll learn how to open and close files in Python. To learn more about the importance of closing your files, check out Why Is It Important to Close Files in Python?. You might also be interested in Context Managers and Python’s with Statement.

00:00 In this lesson, you’ll learn about two different ways to open a file in Python and why you need to close the file afterward. You’ll also look at some good practices for working with files in Python.

00:11 If you’d like to try out the code snippets interactively while following this video, then go ahead and start IDLE now. The first thing you need to do when you want to either read or write data to a file in Python is to open that file by specifying the corresponding path in the file system.

00:30 The quickest way to open a file for reading in Python is by calling the built-in open() function, which at the very minimum expects a string with a filename as the first argument.

00:43 Python will try to find this file in the current working directory, which is where your script is currently running or where you started the interactive Python interpreter.

00:54 When you open IDLE by clicking an icon in your operating system’s menu, then it might run in the location where you installed Python. If your file is located elsewhere, then you can optionally provide a path relative to the current directory or an absolute path that starts at the root of your file system.

01:14 The path may look slightly different depending on which operating system you’re on. For example, Windows uses backslash (\) characters instead of forward slashes as path separators.

01:25 It also comes with multiple file system routes associated with hard drives on your computer. If the file can’t be found in the specified location, you’ll immediately get an error. Otherwise, open() returns an object representation of the file, which you’ll use to interact with the corresponding data stored on disk.

01:47 This object is called a file object or sometimes a file-like object. By default, Python opens files in reading mode, denoted with a letter r, and uses the character encoding specific to your operating system. You’ll learn when and how to change those later.

02:06 It’s a good idea to assign the file object returned by open() to a variable so that you can call one of its methods, so let’s go ahead and do that.

02:19 When you’re done working with a file in Python, you should always close it by calling the .close() method, which tells the operating system that it can safely reclaim the associated resources. In some cases, failing to do so may lead to memory leaks, prevent other programs from accessing your file until you exit Python, or worse, it could irreversibly corrupt your data by not flushing the internal buffer in time. It’s worth noting that once you close a file, you can no longer read the right data to it. To check the state of your file object, you can inspect its .closed attribute.

03:00 In this case, the file is already closed. It’s important to assume that your program could crash at any moment for whatever reason, which can sometimes be completely beyond your control. To ensure that files are eventually closed, even in case of unexpected errors, you can take advantage of a common idiom that relies on the tryfinally clause.

03:22 You can start by declaring your file variable and assigning an initial value of None to it. Then you start a try block in which you make an attempt to open the file.

03:34 Finally, when you’re done processing the file, if the corresponding file object indicated by your file variable exists in memory, then you can close the corresponding file.

03:49 The if statement is necessary here in case the call to the open() function fails, leaving your file variable undefined.

03:57 The finally clause will run unconditionally, regardless of potential exceptions. Now, that’s a bit of a mouthful, don’t you think? Fortunately, because this is such a common idiom, Python provides a more convenient shortcut called the context manager, which can automatically clean up resources for you. In this case, it would call the .close() method on the file object, even if there was an exception. Context managers rely on Python’s with statement. To take advantage of a file object’s context manager, just type the with keyword before calling open()

04:35 and intercept the returned file object using the as keyword, followed by your variable name. This is great because you no longer have to remember to close the file yourself, and the code looks much more readable too. From now on, when you think about reading or writing files in Python, regardless of how you open them, you should always use the with statement to ensure that your files are properly closed.

05:01 Calling open() has been the standard way of working with files in Python for a really long time. However, this built-in function has one drawback.

05:10 It doesn’t provide any abstraction to account for the differences across the operating systems in terms of handling their file paths. You must provide a string to open(), which Python will then try to interpret as a file path. Unfortunately, that might fail, for example, due to the use of the wrong path separator character. To address this problem and make your code more portable, Python 3.4 introduced a new way of opening files through the Path object from the new pathlib module.

05:41 If you haven’t watched the previous video course in this Python Basics series entitled File System Operations, then now would be a good time. That course goes into much more detail about the pathlib module.

05:56 The downside of using pathlib is that you now have to import an additional module. However, once you’ve imported the Path object, you can construct paths with the help of the forward slash operator without worrying about the technical details of a particular file system.

06:11 You can mix Path objects with Python strings as long as one of the values is an instance of the Path class.

06:24 Depending on your operating system, you may get a concrete WindowsPath or PosixPath object, which provides a familiar .open() method. To access that method, let’s first assign your path to a variable.

06:41 Notice that path is not the same as the file. It’s possible that the corresponding file doesn’t even exist on your computer at the moment. To try and open that file, you should use the with statement as before when calling path.open(), and intercept the resulting file object.

06:59 That looks almost exactly the same as calling the built-in open() function, except that the path.open() method doesn’t expect a string as an argument anymore because it already knows your path from the previous line.

07:12 This is the modern and recommended way of opening files in Python projects. However, it doesn’t render the built-in open function completely obsolete, as you don’t always need to take advantage of all the features that pathlib has to offer.

07:26 Sometimes, especially when you quickly test things out, you don’t care about portability. Opening files the old-school way will require fewer keystrokes, while using the pathlib module will be overkill. For this reason, you’ll see a mix of both techniques used throughout this course, depending on which one is more convenient at the given moment. Similarly, while the with statement is almost always the way to go, there will be a few times in this course when it’s easier to show what’s happening under the surface without using one.

07:58 The with statement executes some convenience code, making the individual steps invisible, which doesn’t help explain what’s really going on.

08:09 Okay, let’s quickly recap what you’ve just learned. To read or write data to a file in Python, you need to open that file, for example, by calling the built-in open() function, which expects a suitable filename as an argument.

08:23 The function returns a file-like object that you’ll usually save in a variable. Instead of the filename, you can specify a path relative to the current working directory, or you may specify an absolute path that starts at the root of your file system.

08:39 This can pinpoint a given file unambiguously, but at the same time, it’s the least portable way of specifying a file path because of the differences in the file systems across the platforms.

08:53 When you’re done working with a file object, you must close it by calling the .close() method to avoid data loss or other potential problems. Once closed, a file object is no longer usable in Python.

09:08 If you’d like to learn more about why it’s important to close files in Python and what could happen if you don’t, then check out this Q&A tutorial, which dives into this very topic.

09:20 To ensure that files always get closed, even if an error occurs, you can use the tryfinally clause, which will run the finally block unconditionally.

09:31 However, Python also has an equivalent with statement, which uses the file object’s contact manager to automatically close the file after executing the with block regardless of errors. Therefore, it’s recommended to use the with statement whenever you work with files.

09:50 Finally, instead of calling the built-in open() function, you can create a more versatile Path object imported from the pathlib module and call its .open() method, which works similarly. However, a Path object is a more modern tool for working with files and directories, which can be especially helpful in dealing with cross-platform paths.

10:14 Next up, you’re going to take a closer look at understanding the text and binary files.

Dan Fornoles on June 20, 2023

finnaly gives me a syntax error why?

Martin Breuss RP Team on June 20, 2023

It should be finally with one n and two ls:

try:
    file = open("data.csv")
finally:
    if file:
        file.close()

Dan Fornoles on June 21, 2023

Sorry, the finally clause gives me a syntax error. I tried it several times. With finally, what happens is that the indentation is off. I back-tabbed and typed in finally. It works. No syntax error in this example.

>>> try:
    file = open("deleteme.txt")
    finally:

SyntaxError: invalid syntax
>>> try:
    file = open("deleteme.txt")
finally:
    if file:
        file.close()
>>>

No syntax error.

Martin Breuss RP Team on June 21, 2023

Aha, yes the indentation level is important in Python and part of its syntax. You can learn more about it our article about common reasons for SyntaxErrors.

Nice work figuring it out by yourself :)

Bartosz Zaczyński RP Team on June 21, 2023

@Dan Fornoles IDLE and other Python REPLs indicate indentation with a triple dot (...), so when you start a new code block, it’ll look like this:

>>> try:
...     file = open("deleteme.txt")
... finally:
...     if file:
...         file.close()

Notice that single-line instructions start with a triple chevron (>>>), whereas lines belonging to an indented code block use the triple dot (...) prompt. The lack of those dots in your comment makes me think you may have copied and pasted that code snippet from a text editor with some extra formatting characters.

Become a Member to join the conversation.