I have some Python3 code that opens a file in write mode, writes something to it, and then closes the file. The filename is an int
. For some reason, the code doesn't work as expected. When I run the f.write()
statement, a 6
is printed to the screen. And when I run the f.close()
statement, the string that was supposed to be written is printed to the screen.
>>> f = open(2, 'w')
>>> f.write('FooBar')
6
>>> f.close()
FooBar>>>
>>>
I checked the directory that I ran this in and the file (named 2
) was not created. Can anyone explain what is going on? I suspect it has to do with the filename being an int
, but I'm not sure.
CodePudding user response:
You're passing in a file descriptor number (2 for stderr).
See the documentation for
open()
, emphasis mine:file
is a path-like object giving the pathname (absolute or relative to the current working directory) of the file to be opened or an integer file descriptor of the file to be wrapped.As to why nothing happens before
.close()
(or.flush()
: Your stream is line buffered, and you're not writing a newline.f = open(2, 'wb', buffering=0)
to disable buffering.
If you wish to write to a file called '2'
, you must pass a string.
f = open('2', 'w')
CodePudding user response:
Alternatively to a file name (type str
) open
also accepts a file descriptor (type int
). 2
is the file descriptor of stderr
on Linux, so you are opening the standard error stream for writing, so everything you write to that file object will appear in your terminal/console! The reason it appears only after you do file.close()
is that by default the write content isn't immediately written to the file but rather kept in a buffer which gets written only when a newline \n
is encountered in the write content, and of course when the file is closed. You can force a writeout to file by calling file.flush()
.
The reason for the 6
you get on screen is that the return value of file.write
is always the number of characters that has been written.
In case you wanted to create a file with the name 2
in the current working directory, you need to wrap the 2
in quotes:
>>> f = open("2", 'w')
>>> f.write('FooBar')
6
>>> f.close()
>>>