The only ways I can find in python that redirects the console output to string in a variable also seem to turn off the functionality of displaying the output to the console in a live manner similar to how python would output the code normally.
I currently am changing the sys.stdout but again, this is either one or the other it seems.
If I redefine it, I get the perfect performance for distant error checking, as I am able to save the output variable to a cloud based spreadsheet in the event of exception handling, which sends me notifications anywhere that I am.
However, redefining it means I don't get to come and locally check on the output of the program while it is "running smoothly"
EDIT: some of your answers have helped me refine my question. Here is a fresh re wording:
What is the best way to concisely store and record outputs with a single variable as the elements are printed to the console without overwriting sys.stdout?
old_stdout = sys.stdout
new_stdout = io.StringIO()
sys.stdout = new_stdout
def update_error_log_ss(traceback_, summary, output = ""):
print("Connecting to Smart Sheet to Update Error Log")
token = 'token'
error_log_sheetid = 00000000
ss_client = ss.Smartsheet(token)
now = datetime.datetime.now()
sheet = ss_client.Sheets.get_sheet(error_log_sheetid)
colid = []
for col in sheet.columns:
colid.append(col.id)
print(str(col.id) + " - " + col.title)
totalcols = len(colid)
row_add = ss.models.Row()
row_add.to_top = True
row_add.cells.append({
'column_id': colid[0],
'value': str(now)
})
row_add.cells.append({
'column_id': colid[1],
'value': summary
})
row_add.cells.append({
'column_id': colid[2],
'value': traceback_
})
row_add.cells.append({
'column_id': colid[3],
'value': output
})
response = ss_client.Sheets.add_rows(
error_log_sheetid,
[row_add]
)
return
except Exception:
if debug_ == False:
synch.update_error_log_ss(traceback.format_exc(),'initialization failure',new_stdout.getvalue())
main_()
else:
synch.update_error_log_ss(traceback.format_exc(),'initialization failure')
main_()
The only issue I have with the above solution is that in order for new_stdout.getvalue() to get defined, sys.stdout has to be overwritten
According to the print
docs:
The file argument must be an object with a
write(string)
method
So you can just create one for your needs and assign it to sys.stdout
which is the default file
argument for print
:
import io
import sys
class my_stdout:
def __init__(self):
self.real_stdout = sys.stdout
self.new_stdout = io.StringIO()
def write(self, s):
self.real_stdout.write(s)
self.new_stdout.write(s)
def getvalue(self):
return self.new_stdout.getvalue()
new_stdout = my_stdout()
sys.stdout = new_stdout
print("Original: Hello world!")
# for debug:
sys.stdout = new_stdout.real_stdout
print("From stringio:", new_stdout.getvalue())
Output:
Original: Hello world!
From stringio: Original: Hello world!