ValueError: I/O operation on closed file error because of sys.stdout

Question:

I am recently learning Python. I wrote the following code and I want to continue writing something in console after closing sys.stdout with writing in txt, but I get an error.

I need to close sys.stdout and continue get information from print('Hello') in console, but that doesn’t work. Please, i would be glad if you provide code on how to solve this problem.

Code:

from selenium import webdriver
from selenium.webdriver.common.by import By 
import sys    

print('getting contests-url')
sys.stdout = open('out.txt', 'w')
find_href = driver.find_elements(By.CLASS_NAME, 'discussionListItem')

for my_href in find_href:
    print(my_href.get_attribute('id'))

sys.stdout.close()
print('Hello')

Output:

print('Hello')

ValueError: I/O operation on closed file.
Asked By: kgjfdhvd

||

Answers:

To move sys.stdout back to the original one:

from selenium import webdriver
from selenium.webdriver.common.by import By 
import sys    

print('getting contests-url')
sys.stdout = open('out.txt', 'w')
find_href = driver.find_elements(By.CLASS_NAME, 'discussionListItem')

for my_href in find_href:
    print(my_href.get_attribute('id'))

sys.stdout.close()
sys.stdout = sys.__stdout__
print('Hello')

However, to actually redirect stdout in a Pythonic fashion, use contextlib.redirect_stdout:

from contextlib import redirect_stdout

from selenium import webdriver
from selenium.webdriver.common.by import By 

print('getting contests-url')
with open("out.txt", "w") as out:
    with redirect_stdout(out):
        find_href = driver.find_elements(By.CLASS_NAME, 'discussionListItem')

        for my_href in find_href:
            print(my_href.get_attribute('id'))

print('Hello')
Answered By: pigrammer

Rather than do anything tricky with the streams, open the file in a normal way (using a with block so that it will be closed automatically), and simply use print to write to the file directly:

from selenium import webdriver
from selenium.webdriver.common.by import By 
import sys    

print('getting contests-url')
with open('out.txt', 'w') as out:
    find_href = driver.find_elements(By.CLASS_NAME, 'discussionListItem')
    for my_href in find_href:
        print(my_href.get_attribute('id'), file=out)

print('Hello')

If you don’t actually need any of the special functionality of print, and just want to write a string to the file, use its .write method:

from selenium import webdriver
from selenium.webdriver.common.by import By 
import sys    

print('getting contests-url')
with open('out.txt', 'w') as out:
    find_href = driver.find_elements(By.CLASS_NAME, 'discussionListItem')
    for my_href in find_href:
        out.write(my_href.get_attribute('id'))

print('Hello')
Answered By: Karl Knechtel
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.