Why do I get a ValueError when stdout is explicitly closed?

Python newbie here. I am writing a script that can upload some output to a file or stdout, depending on the arguments passed to it. When interpreting the arguments, I assign the file open 'ed or stdout global variable called output_file , which can be used by the rest of the script to write the output no matter what type of stream was selected. At the very end of the script, I close output_file . This needs to be done for the file stream, and although it is redundant for stdout, my experience with other programming languages โ€‹โ€‹suggests that there is no harm in explicitly closing stdout just before the program terminates.

However, when stdout is used for output (and subsequently closed), I get a ValueError: 'I / O operation in a closed file.' ". I know that this error is not directly caused by my call to close stdout, but it arises after returning my script. My question is: why is this happening, and is there a way to manually close stdout without running it? (I know that I can easily get around the problem by conditionally closing the stream only when the file was selected, but I want to know if / why it is necessary.)

A very simple demo fragment:

 from sys import stdout stdout.close() 
+4
source share
4 answers

The problem is that on python-3.2 was an attempt to disable stdout reset without checking if it is closed.

issue13444 about this.

You should not have this problem in python-2.7 in versions after the fix .

+5
source

Once you have closed stdout this way, you should be absolutely sure that nothing will try to print anything to stdout . If you do something, you get this exception.

My recommendation would be to close output_file conditionally:

 if output_file != sys.stdout: output_file.close() 

edit Here is an example where sys.stdout closed at the very end of the script, and yet it creates a ValueError: 'I/O operation on closed file at startup.

 import atexit @atexit.register def goodbye(): print "You are now leaving the Python sector." import sys sys.stdout.close() 
+4
source

Before closing, you can check the output_file.closed file:

 if not output_file.closed: output_file.close() 

And make sure you don't have any I / O calls to the output_file after closing.

0
source

To resolve this error, two things must be done: reset (i) reset stdout; (ii) do not close stdout, close the file to which it was redirected.

 f=open(filename, 'w') sys.stdout = f print("la la-la"), file = sys.stdout) f.close() sys.stdout = sys.__stdout__ 

Various solutions to this problem involve copying the "original" stdout pointer to a variable before assigning stdout to a file (i.e., original = stdout ... stdout = f), and then copying it back (stdout = original). But they neglect to mention the final operation in their routine, which wastes your hair in vain.

Found a solution here .

0
source

Source: https://habr.com/ru/post/1394838/


All Articles