What can we write inside of a `with … as` code block?

Question

What can we write inside of a with … as code block?

Answer

Any code you would normally write outside of a block to work with a file could be written inside of a with-as code block.
Just be sure to indent your code using 2 spaces (on Codecademy, anyway) per indentation level, otherwise Python won’t know that you intended for the code to be part of the with-as block. Failing to indent will cause an error if you try accessing anything you created inside of that code block, or trying to access the file variable.

1 Like
with open("text.txt", "w") as textfile:
  textfile.write("Success!")

What happens if i want to print the text i’ve written to the console? I understand that textfile.read() wouldn’t work in this case because the textfile is automatically closed before i have a chance to read textfile

1 Like

Use read mode and print the result of read() method.

with open("text.txt", "r") as f:
  print(f.read()) 

>>> Success!

The file is automatically closed at the end of the with statement. So within the with block you can do whatever you want.

1 Like

Hi @systemace16942,

You also can save the contents of the file to a variable, enabling you to use those contents at any time later on, even after the file has been closed …

with open("text.txt", "r") as f:
  text_content = f.readlines()
# ... later on ...
for line in text_content:
  print(line.strip())
5 Likes

You’d probably want to close it before reading anyway. Reading and writing with the same file can lead to some confusing behaviour that can easily be ruled out by doing one at a time.
If you did need to both read and write data your first thought should be to load the whole file into memory and work on it there.

Also, it only closes when you exit the context handler. But, yeah, that wasn’t what you wanted to do anyway.

1 Like

Clear and succinct, thank you!

What if i were to use open(“text.txt”, “r+”) instead? How would the code vary?

with open("text.txt", "r+") as my_file:
  my_file.write("SUCCESS!")
  print my_file.read()

I tried using the code above but there wasn’t anything printed to the console

1 Like

Your position in the file is at the end. Reading from there will give you nothing, you’d have to go back to the top of the file.
You might also need to flush after writing before you read, don’t know.
Performance might suffer horribly, you might run into operating system-specific behaviours.

There are programs that do this, databases in particular. I know just enough to avoid it.

2 Likes

As @ionatan has explained, your “pointer” is at the end of the document after your write() method. So, you should use another with ... as block to read the file.

3 Likes

Hi, may i know what do you mean by “pointer” being at the end of the document? Would it be possible for you to put it in layman terms?

In Python Files I/O, different modes place the pointer at different position of the file.

For example, we know that the r+ mode places the pointer at the beginner of the file:

with open("text.txt", "r+") as f:
  f.write("Success!")
  f.seek(0)
  print(f.read())
 
>>> Success!

We can then use the seek(0) method to reposition the pointer at the beginner of the file, and print the whole file.

As oppose, the a append mode places the pointer at the end of the file, so you can add new content to existing file.

Reference:

  1. Python - Files I/O (Tutorialspoint)
3 Likes

I see! Very, very clear! Thank you so much! So the reason my code was wrong was because i wrote in text.txt and tried to read AFTER i wrote the code, which therefore puts my cursor at the end of the code and hence printed nothing. As such, for the code to run, I have to use my_file.seek() to position my cursor back at the start of the document.

3 Likes

Actually I just want to add other application of with ... as:

with sql.connect("database.db") as con:
      name = "foobar"
      cur = con.cursor()
      cur.execute("INSERT INTO students (name) VALUES (?)",(name))
      con.commit()
      msg = "Done"

Basically skips the need for con.close() and clears up memory.

I find this typical and useful when writing backend api using Flask.

i do not see anything in the file. it looks like the code does not work.
or there is something im missing?

1 Like