1

What is the difference between

os.close(sys.stdout.fileno())

and

sys.stdout.close()

I read the docs and it looks like they do the same thing but sometimes when I call the former I get a bad file descriptor error.

Ogen
  • 6,499
  • 7
  • 58
  • 124

2 Answers2

5

Please read this post: sys.stdout and os.close

Python file objects are a high-level layer of abstraction on top of C stdio streams, which in turn are a medium-level layer of abstraction on top of (among other things) low-level C file descriptors.

For most file objects you create in Python via the builtin open constructor, calling close marks the Python file object as being closed from Python’s point of view, and also arranges to close the underlying C stream. This also happens automatically in f‘s destructor, when f becomes garbage.

But stdin, stdout and stderr are treated specially by Python, because of the special status also given to them by C. Calling sys.stdout.close marks the Python-level file object as being closed, but does not close the associated C stream.

To close the underlying C stream for one of these three, you should first be sure that this is what you really want to do (e.g., you may confuse extension modules trying to do I/O). If it is, use os.close:

os.close(0)   # close C's stdin stream
os.close(1)   # close C's stdout stream
os.close(2)   # close C's stderr stream
James Sapam
  • 16,036
  • 12
  • 50
  • 73
2

You probably don't want to do the former. It will close the file descriptor underlying sys.stdout. Later when sys.stdout gets deallocated (e.g. if you reassign it) you will get an error because stdout's file descriptor has abruptly gone away (from the point of view of the Python object).

Worse, if you opened some other file in the meantime, the file descriptor could get reused, and sys.stdout would happily close that one, leading to even more trouble.

Always use the latter. Safer, more portable, and saner.

nneonneo
  • 171,345
  • 36
  • 312
  • 383