Files

This section covers how to read from files in Python and how to write to them.

You need three steps to read text from a file:

  • open the file,
  • read something from it,
  • and finally close it.

Create a poem.txt file in the editor and write any poem into it. Save the file.

I recommend to use the same editor that you use for your Python program to edit the file with the poem.

If you use a different editor than Atom, be sure to keep in mind when coding:

  • If the editor offers you a choice of encoding, choose UTF-8.
  • If UTF-8 without BOM is available, use it.
  • If you have to use Notepad then use the non-standard utf-8-sig instead.

utf-8 is the name of the standard encoding. You can store any emoji or accented characters to files with this encoding. 🎉

Write this program:

poem_file = open('poem.txt', encoding='utf-8')
content = poem_file.read()
print(content)
poem_file.close()

Run it in the directory with poem.txt. In other words, the current working directory must contain the file with the poem.

The program prints the poem!

What's going on here? The open() function returns the value that represents the open file. This value has its own methods. We are using the read() method that reads the entire contents of the file at once and returns it as a string. We will cover close(), the function that closes the open file, later.

Iteration over files

You can use open files with the for statement. It's similar as with strings or ranges. for i in range provides consecutive numbers. for c in 'abcd' provides single string characters. for line in poem_file provides individual lines read from the file into the line variable.

For example, we can indent the poem to make it stand out of the text.

print('I heard this poem:')
print()
poem_file = open('poem.txt', encoding='utf-8')
for line in poem_file:
    print('    ' + line)
poem_file.close()
print()
print('How do you like it?')

When you try it, you will find that the spacing is not how it should be. Would you like to try to explain why this is so?

Řešení

Closing files

It is quite important to close the file after the program stops using it. The close() method does this for us. Operating systems have limits on open files. If you do not close them you can exceed this limit. Besides, on Windows, you cannot re-open a file that is already open.

You can compare files to a fridge: If you want to put something into the fridge, you need to open it and then close it. The fridge works without closing, too, but then something goes rotten.

It is easy to forget to close a file. For example, an exception or return statement inside the file processing may skip the close(). Then the file remains open.

We can use the try/finally statement to make sure that the file is closed.

The finally block (the statements(s) after finally) is always executed. It executes no matter if the try blocks ends with success, or with an exception, or if you jump out of it using return or break.

def initial_character():
    """Return the first character in the poem."""

    poem_file = open('poem.txt', encoding='utf-8')
    try:
        content = poem_file.read()
        return content[0]
    finally:
        poem_file.close()

print(initial_character())

You can use the finally block every time you need to close or terminate something -- not just a file, it can also be a database connection.

The with statement

Because the try/finally block is quite verbose, there is a better way in Python. It's the with statement:

def initial_character():
    """Return the first character in the poem."""

    with open('poem.txt', encoding='utf-8') as poem_file:
        content = poem_file.read()
        return content[0]

print(initial_character())

We used this statement for testing before. It wraps a block with an expected exception. It checks if the correct exception has occurred after the block ends. In our case, the file is closed when the block ends no matter what has happened. The file is closed in all cases --
if the with block ends with success, or with an exception, or if we're jumping out of it.

The with statement is the best option for working with files in the majority of cases.

Writing to files

Caution!

It is easy to delete or overwrite any file in Python. Try the following examples in a directory where you have nothing important!

You can write to a file in Python. You need to open the file for writing using a named argument mode='w' (w stands for write). You can write individual strings using the write() method.

If the file already exists, opening it with mode='w' overwrites its original content. There will be only the text that your program writes into it.

with open('second-poem.txt', mode='w', encoding='utf-8') as poem_file:
    poem_file.write('Our old chiming clock\n')
    poem_file.write("Is beating four o'clock\n")

Why is there a `\n`?

The write() method does not put a line ending after the string. If you need to write multiple lines to files, you need to
end each of them by a newline character '\n'. We have described it in the Strings section.

Or, you can use the print() function. By default, it writes to the terminal. It can also write into an open file if you use the named argument file.

Other print() options remain unchanged. These options include line ending, conversion to strings, and printing multiple arguments at a time.

with open('second-poem.txt', mode='w', encoding='utf-8') as poem_file:
    print('Our old chiming clock', file=poem_file)
    print('Is beating', 2+2, "o'clock", file=poem_file)
{
  "data": {
    "sessionMaterial": {
      "id": "session-material:2018/pyladies-en-prague:git:1",
      "title": "Files",
      "html": "\n          \n    \n\n    <h1>Files</h1>\n<p>This section covers how to read from files in Python \nand how to write to them.</p>\n<p>You need three steps to read text from a file:</p>\n<ul>\n<li><em>open</em> the file,</li>\n<li><em>read</em> something from it,</li>\n<li>and finally <em>close</em> it.</li>\n</ul>\n<p>Create a <code>poem.txt</code> file in the editor and write any poem into it.\nSave the file.</p>\n<div class=\"admonition note\"><p>I recommend to use the same editor that you use for your \nPython program to edit the file with the poem.</p>\n<p>If you use a different editor than Atom, be sure to keep in mind when coding:</p>\n<ul>\n<li>If the editor offers you a choice of encoding, choose <code>UTF-8</code>.</li>\n<li>If <code>UTF-8 without BOM</code> is available, use it.</li>\n<li>If you have to use Notepad then use the non-standard <code>utf-8-sig</code> instead.</li>\n</ul>\n<p><a href=\"https://en.wikipedia.org/wiki/UTF-8\"><code>utf-8</code></a> is the name of the standard encoding.\nYou can store any emoji or accented characters to files with this encoding.\n&#x1F389;</p>\n</div><p>Write this program:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"n\">poem_file</span> <span class=\"o\">=</span> <span class=\"nb\">open</span><span class=\"p\">(</span><span class=\"s1\">&apos;poem.txt&apos;</span><span class=\"p\">,</span> <span class=\"n\">encoding</span><span class=\"o\">=</span><span class=\"s1\">&apos;utf-8&apos;</span><span class=\"p\">)</span>\n<span class=\"n\">content</span> <span class=\"o\">=</span> <span class=\"n\">poem_file</span><span class=\"o\">.</span><span class=\"n\">read</span><span class=\"p\">()</span>\n<span class=\"k\">print</span><span class=\"p\">(</span><span class=\"n\">content</span><span class=\"p\">)</span>\n<span class=\"n\">poem_file</span><span class=\"o\">.</span><span class=\"n\">close</span><span class=\"p\">()</span>\n</pre></div><p>Run it in the directory with <code>poem.txt</code>. In other words, the current working \ndirectory must contain the file with the poem.</p>\n<p>The program prints the poem!</p>\n<p>What&apos;s going on here?\nThe <code>open()</code> function returns the value that represents the <em>open file</em>.\nThis value has its own methods.\nWe are using the <code>read()</code> method that reads the entire contents \nof the file at once and returns it as a string.\nWe will cover <code>close()</code>, the function that closes the open file, later.</p>\n<h2>Iteration over files</h2>\n<p>You can use open files with the <code>for</code> statement. \nIt&apos;s similar as with strings or ranges.\n<code>for i in range</code> provides consecutive numbers. \n<code>for c in &apos;abcd&apos;</code> provides single string characters. \n<code>for line in poem_file</code> provides individual lines read from the file into the <code>line</code> variable.</p>\n<p>For example, we can indent the poem to make it stand out of the text.</p>\n<div class=\"highlight\"><pre><span></span><span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s1\">&apos;I heard this poem:&apos;</span><span class=\"p\">)</span>\n<span class=\"k\">print</span><span class=\"p\">()</span>\n<span class=\"n\">poem_file</span> <span class=\"o\">=</span> <span class=\"nb\">open</span><span class=\"p\">(</span><span class=\"s1\">&apos;poem.txt&apos;</span><span class=\"p\">,</span> <span class=\"n\">encoding</span><span class=\"o\">=</span><span class=\"s1\">&apos;utf-8&apos;</span><span class=\"p\">)</span>\n<span class=\"k\">for</span> <span class=\"n\">line</span> <span class=\"ow\">in</span> <span class=\"n\">poem_file</span><span class=\"p\">:</span>\n    <span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s1\">&apos;    &apos;</span> <span class=\"o\">+</span> <span class=\"n\">line</span><span class=\"p\">)</span>\n<span class=\"n\">poem_file</span><span class=\"o\">.</span><span class=\"n\">close</span><span class=\"p\">()</span>\n<span class=\"k\">print</span><span class=\"p\">()</span>\n<span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s1\">&apos;How do you like it?&apos;</span><span class=\"p\">)</span>\n</pre></div><p>When you try it, you will find that the spacing is not how it should be. \nWould you like to try to explain why this is so?</p>\n<div class=\"solution\" id=\"solution-0\">\n    <h3>&#x158;e&#x161;en&#xED;</h3>\n    <div class=\"solution-cover\">\n        <a href=\"/2018/pyladies-en-prague/beginners-en/files/index/solutions/0/\"><span class=\"link-text\">Uk&#xE1;zat &#x159;e&#x161;en&#xED;</span></a>\n    </div>\n    <div class=\"solution-body\" aria-hidden=\"true\">\n        <p>Each row ends with a newline character (<code>&apos;\\n&apos;</code>).\nWhen iterating over a Python file, \nthis character remains at the end of the string <code>line</code> &#xB9;.\nThe <code>print()</code> function then adds another newline character. \nThis function always ends the line. \nYou can suppress it using the argument <code>end=&apos;&apos;</code>).\nThat is one way how to &quot;fix&quot; this extra spacing. \nThe other is to use the method <code>rstrip()</code> for each line. \nThis method removes all spaces and newline characters \nthat are the end of the string.</p>\n<hr>\n<p>&#xB9;  Why does Python keep the newline character? If the <code>&apos;\\n&apos;</code> at the end of line was removed, \nit would not be possible to know if the last line ended with <code>&apos;\\n&apos;</code> or not.</p>\n    </div>\n</div><h2>Closing files</h2>\n<p>It is quite important to close the file after the program stops using it. \nThe <code>close()</code> method does this for us.\nOperating systems have limits on open files.\nIf you do not close them you can exceed this limit.\nBesides, on Windows, you cannot re-open a file that is already open.</p>\n<p>You can compare files to a fridge: If you want to put something into the fridge, \nyou need to open it and then close it.\nThe fridge works without closing, too, but then something goes rotten.</p>\n<p>It is easy to forget to close a file.\nFor example, an exception or <code>return</code> statement inside \nthe file processing may skip the <code>close()</code>.\nThen the file remains open.</p>\n<p>We can use the <code>try/finally</code> statement to make sure that the file is closed.</p>\n<p>The <code>finally</code> block (the statements(s) after <code>finally</code>) is always executed.\nIt executes no matter if the <code>try</code> blocks ends with success, \nor with an exception, or if you jump out of it using <code>return</code> or <code>break</code>.</p>\n<div class=\"highlight\"><pre><span></span><span class=\"k\">def</span> <span class=\"nf\">initial_character</span><span class=\"p\">():</span>\n    <span class=\"sd\">&quot;&quot;&quot;Return the first character in the poem.&quot;&quot;&quot;</span>\n\n    <span class=\"n\">poem_file</span> <span class=\"o\">=</span> <span class=\"nb\">open</span><span class=\"p\">(</span><span class=\"s1\">&apos;poem.txt&apos;</span><span class=\"p\">,</span> <span class=\"n\">encoding</span><span class=\"o\">=</span><span class=\"s1\">&apos;utf-8&apos;</span><span class=\"p\">)</span>\n    <span class=\"k\">try</span><span class=\"p\">:</span>\n        <span class=\"n\">content</span> <span class=\"o\">=</span> <span class=\"n\">poem_file</span><span class=\"o\">.</span><span class=\"n\">read</span><span class=\"p\">()</span>\n        <span class=\"k\">return</span> <span class=\"n\">content</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span>\n    <span class=\"k\">finally</span><span class=\"p\">:</span>\n        <span class=\"n\">poem_file</span><span class=\"o\">.</span><span class=\"n\">close</span><span class=\"p\">()</span>\n\n<span class=\"k\">print</span><span class=\"p\">(</span><span class=\"n\">initial_character</span><span class=\"p\">())</span>\n</pre></div><p>You can use the <code>finally</code> block every time you need \nto close or terminate something -- not just a file,\nit can also be a database connection.</p>\n<h2>The <code>with</code> statement</h2>\n<p>Because the <code>try/finally</code> block is quite verbose, \nthere is a better way in Python. It&apos;s the <code>with</code> statement:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"k\">def</span> <span class=\"nf\">initial_character</span><span class=\"p\">():</span>\n    <span class=\"sd\">&quot;&quot;&quot;Return the first character in the poem.&quot;&quot;&quot;</span>\n\n    <span class=\"k\">with</span> <span class=\"nb\">open</span><span class=\"p\">(</span><span class=\"s1\">&apos;poem.txt&apos;</span><span class=\"p\">,</span> <span class=\"n\">encoding</span><span class=\"o\">=</span><span class=\"s1\">&apos;utf-8&apos;</span><span class=\"p\">)</span> <span class=\"k\">as</span> <span class=\"n\">poem_file</span><span class=\"p\">:</span>\n        <span class=\"n\">content</span> <span class=\"o\">=</span> <span class=\"n\">poem_file</span><span class=\"o\">.</span><span class=\"n\">read</span><span class=\"p\">()</span>\n        <span class=\"k\">return</span> <span class=\"n\">content</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span>\n\n<span class=\"k\">print</span><span class=\"p\">(</span><span class=\"n\">initial_character</span><span class=\"p\">())</span>\n</pre></div><p>We used this statement for testing before. \nIt wraps a block with an expected exception.\nIt checks if the correct exception has occurred \nafter the block ends.\nIn our case, the file is closed when the block ends\nno matter what has happened.\nThe file is closed in all cases --<br>\nif the <code>with</code> block ends with success, \nor with an exception, or if we&apos;re jumping out of it.</p>\n<p>The <code>with</code> statement is the best option for working with files\nin the majority of cases.</p>\n<h2>Writing to files</h2>\n<div class=\"admonition warning\"><p class=\"admonition-title\">Caution!</p>\n<p>It is easy to delete or overwrite any file in Python.\nTry the following examples in a directory where you have nothing important!</p>\n</div><p>You can write to a file in Python.\nYou need to open the file for writing using a named argument\n<code>mode=&apos;w&apos;</code> (<code>w</code> stands for <em>write</em>).\nYou can write individual strings using the <code>write()</code> method.</p>\n<p>If the file already exists, opening it with <code>mode=&apos;w&apos;</code> overwrites \nits original content. There will be only the text that your program \nwrites into it.</p>\n<div class=\"highlight\"><pre><span></span><span class=\"k\">with</span> <span class=\"nb\">open</span><span class=\"p\">(</span><span class=\"s1\">&apos;second-poem.txt&apos;</span><span class=\"p\">,</span> <span class=\"n\">mode</span><span class=\"o\">=</span><span class=\"s1\">&apos;w&apos;</span><span class=\"p\">,</span> <span class=\"n\">encoding</span><span class=\"o\">=</span><span class=\"s1\">&apos;utf-8&apos;</span><span class=\"p\">)</span> <span class=\"k\">as</span> <span class=\"n\">poem_file</span><span class=\"p\">:</span>\n    <span class=\"n\">poem_file</span><span class=\"o\">.</span><span class=\"n\">write</span><span class=\"p\">(</span><span class=\"s1\">&apos;Our old chiming clock</span><span class=\"se\">\\n</span><span class=\"s1\">&apos;</span><span class=\"p\">)</span>\n    <span class=\"n\">poem_file</span><span class=\"o\">.</span><span class=\"n\">write</span><span class=\"p\">(</span><span class=\"s2\">&quot;Is beating four o&apos;clock</span><span class=\"se\">\\n</span><span class=\"s2\">&quot;</span><span class=\"p\">)</span>\n</pre></div><div class=\"admonition note\"><p class=\"admonition-title\">Why is there a `\\n`?</p>\n<p>The <code>write()</code> method does not put a line ending after the string.\nIf you need to write multiple lines to files, you need to<br>\nend each of them by a newline character <code>&apos;\\n&apos;</code>. We have described it\nin the&#xA0;<a href=\"/2018/pyladies-en-prague/beginners-en/str/\">Strings section</a>.</p>\n</div><p>Or, you can use the <code>print()</code> function.\nBy default, it writes to the terminal. \nIt can also write into an open file if you use the named argument <code>file</code>.</p>\n<p>Other <code>print()</code> options remain unchanged. These options include\nline ending, conversion to strings, and printing multiple arguments at a time.</p>\n<div class=\"highlight\"><pre><span></span><span class=\"k\">with</span> <span class=\"nb\">open</span><span class=\"p\">(</span><span class=\"s1\">&apos;second-poem.txt&apos;</span><span class=\"p\">,</span> <span class=\"n\">mode</span><span class=\"o\">=</span><span class=\"s1\">&apos;w&apos;</span><span class=\"p\">,</span> <span class=\"n\">encoding</span><span class=\"o\">=</span><span class=\"s1\">&apos;utf-8&apos;</span><span class=\"p\">)</span> <span class=\"k\">as</span> <span class=\"n\">poem_file</span><span class=\"p\">:</span>\n    <span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s1\">&apos;Our old chiming clock&apos;</span><span class=\"p\">,</span> <span class=\"nb\">file</span><span class=\"o\">=</span><span class=\"n\">poem_file</span><span class=\"p\">)</span>\n    <span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s1\">&apos;Is beating&apos;</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"o\">+</span><span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"s2\">&quot;o&apos;clock&quot;</span><span class=\"p\">,</span> <span class=\"nb\">file</span><span class=\"o\">=</span><span class=\"n\">poem_file</span><span class=\"p\">)</span>\n</pre></div>\n\n\n        "
    }
  }
}