Two ways of saving output to a file. Which one is better ? and why?

What’s the proper way of saving an output to a text file ?
Both codes give the same result.

file1 = open('output_test1.txt', 'w')
for x in range(9):
    print(x, file =file1)

file1 = open('output_test2.txt', 'w')
for x in range(9):
    file1.write(str(x) + '\n')

“Better” with code usually means “more accurately represents a programmer’s intent”. So what is the intent here?

You have already demonstrated one advantage of using the print() function: it converts the object into a ‘string’.

So, if you want to write ‘strings’ to a file, then it’s less coding (and maybe more ‘human readable’) to employ that functionality.

1 Like

I often collaborate. It would be nice if I share common codes (more used) and avoid less used codes.
So, I mean “popular” by “better”

So, you prefer the print()… thanks for your response.
Let’s hear what the others think about it.

You’re welcome.

For writing string objects, yes, I’ll use the print() function, because one can use all the functionality that has been provided, rather than having to construct the object in code.

Speaking to your thread title: is that a “better” way? I think so, for that particular use case.

The only other points of note that I would pick up on is:

  1. You’ve not coded that with a file handler.
  2. You’ve not specified the encoding.

So, I would code that as:

file1 = "output_test1.txt"
with open(file1, mode='w', encoding='UTF-8') as output:
    for x in range(9):
        print(x, file=output)

Then pick either one, share it around! That’ll make it more common, more used, and thus better.

I prefer write in some cases.

If you want to write a message to stdout while writing to a file, a mixture of print(…) and print(…, file=o) makes the code a bit less visible.

Cannot use print for binary mode stream.
It’s a matter of style, but I don’t like mixing print and write in the same module.

1 Like

Is “with open … as” called the file handler ?
I already have it in the original code, like this: (I’ll add the encoding soon)

with open("output_test1.txt, mode='w') as output:
    for x in range(9):
        print(x, file=output)

Should I close it ? or not necessary ?

A good point.
Yet, I think i’ll stick with Print(x, file)
Once in the future I have to code two lines, I’ll then use Write()

Yes. The with open() loop is called a ‘file handler’ ‘context manager’ and you don’t need the .close(), because that’s taken care of when the code drops out of the loop.

Edit for correction.

1 Like

Most style issues are subjective. If you can’t get an answer from e.g. PEP 8, you should seek opinions from the people you are collaborating with.

I’m going to be opinionated here:

Don’t use print to write to a file:

  • print provides various “magic” (like adding new lines and spaces between items) which is handy for, quick printing to the screen, but makes it more awkward to precisely control the file contents.
  • Using print to write to a file hides that it’s not printing to the screen, it will make your code harder to read.

Anyway, I don’t hink I’ve ever seen print used this way in real code. :slight_smile:

So why does print have an optional file parameter for the output? I think it is for uses like:

print("Oops something went wrong", file=sys.stderr)

That is, when you still want quick and easy printing to the screen :slight_smile:

If you DO what to capture output similar to what would be written to the console, you can redirect stdout:

with  open("console_output.txt", 'w', encoding="utf-8") as outfile:
    with contextlib.redirect_stdout(outfile):
        print("this should go to the file")

Well… I wouldn’t call it that. It’s a with-statement:

and a with-statement runs a context manager:

obtained from the expression (open(....)).

A context manager runs some setup code before the suite inside the
with-statement and some teardown code when you exit the suite (either by
falling through or if an exception happens).

When you write:

 with open(.....) as f:
     do something with f

Python obtains a file object from the open() call, and binds the name
f to it (which lets you refer to it during the inner suite).

Before running the suite (“do something with f”) the with-statement
calls f.__enter__() for any setup (for a file, nothing) and after
running the suite it calls f.__exit__(.....) to do any tear down, in
this case that will close the file.

I suspect Rob might be conflating the term “file handle” with this
stuff. To me, “file handle” is a UNIX thing, the internal state of an
open file (such as its read/write poistion and whether it is open for
read and/or write etc). Some of the functions in the os model such as return a “file descriptor”, which is an integer we use to
refer to the file handle in system calls.

Cameron Simpson

1 Like

Cameron is correct; I have my terminology mixed up: a ‘context manager’ is the term I should have used.