Reputation: 393
I just want to make the print
output redirect to a file. my code as below:
import sys
# define the log file that receives your log info
log_file = open("message.log", "w")
# redirect print output to log file
sys.stdout = log_file
print ("Now all print info will be written to message.log")
# any command line that you will execute
...
log_file.close()
print ("Now this will be presented on screen")
After execute the script, it comes an error:
[~/Liaohaifeng]$ python3 log.py
Traceback (most recent call last):
File "log.py", line 14, in <module>
print ("Now this will be presented on screen")
ValueError: I/O operation on closed file.
why does this happen? if I update my script as below:
import sys
# make a copy of original stdout route
stdout_backup = sys.stdout
# define the log file that receives your log info
log_file = open("message.log", "w")
# redirect print output to log file
sys.stdout = log_file
print ("Now all print info will be written to message.log"
# any command line that you will execute
...
log_file.close()
# restore the output to initial pattern
sys.stdout = stdout_backup
print ("Now this will be presented on screen")
It will be OK. So, could you please kindly tell me the theory in this issue?
Upvotes: 0
Views: 65
Reputation: 1045
As mentioned in comments, print
does not print to a closed filehandle and you have closed sys.stdout
, potentially breaking any prints evoked after it closed. Which may happen even without your knowledge, eg somewhere in the imported code. That's why you shouldn't fiddle with sys.*
variables (or any variables you didn't create, really) unless you absolutely need to. There is a proper way to redirect print
output to a file and it goes like this:
log_file = open('message.log', 'w')
print('Stuff to print in the log', file=log_file)
log_file.close()
Or even safer like this:
with open('message.log', 'w') as log_file:
# Do stuff
print('Stuff to print in the log', file=log_file)
The handle will automatically flush and close when the with
block finishes.
Upvotes: 1