英文:
How to get all previous print in Python
问题
I'm currently using some functions to store all print
in Python. And it gets all print
AFTER the function has finished. Here is a sample snippet:
import io
import sys
import time
import traceback
def return_std(func):
def wrapper(*args, **kwargs):
old_stdout = sys.stdout
sys.stdout = buffer = io.StringIO()
try:
func(*args, **kwargs)
except:
print(traceback.format_exc())
finally:
sys.stdout = old_stdout
body = buffer.getvalue()
buffer.close()
sys.stdout = old_stdout # Move this line here to see output instantly
return body
return wrapper
@return_std
def some_useful_function():
print('so this line is executed at ' + time.strftime('%X'))
time.sleep(5)
print('program execute at ' + time.strftime('%X'))
std_of_some_useful_function = some_useful_function()
print(std_of_some_useful_function)
print('but we cannot know if it succeeded or failed before ' + time.strftime('%X'))
Output:
program execute at 11:11:11
so this line is executed at 11:11:11
but we cannot know if it succeeded or failed before 11:11:16
I moved sys.stdout = old_stdout
inside the finally
block to see the output instantly and store all previous print
at 11:11:16
.
英文:
I'm currently using some functions to store all print
in Python
And it get all print
AFTER the function has finished
Here is a sample snippet
import io
import sys
import time
import traceback
def return_std(func):
def wrapper(*args, **kwargs):
old_stdout = sys.stdout
sys.stdout = buffer = io.StringIO()
try:
func(*args, **kwargs)
except:
print(traceback.format_exc())
finally:
sys.stdout = old_stdout
body = buffer.getvalue()
buffer.close()
return body
return wrapper
@return_std
def some_useful_function():
print('so this line is executed at ' + time.strftime('%X'))
time.sleep(5)
print('program execute at ' + time.strftime('%X'))
std_of_some_useful_function = some_useful_function()
print(std_of_some_useful_function)
print('but we can not know if it succeeded or failed before ' + time.strftime('%X'))
output
program execute at 11:11:11
so this line is executed at 11:11:11
but we can not know if it succeeded or failed before 11:11:16
This way captures all print
and error in some_useful_function
, and stores it as the function return. But print
will not show BEFORE this function has finished
How should I modify the wrapper return_std
, so I can see the output at 11:11:11
instantly (like it was really printed), and get all previous print
stored at 11:11:16
答案1
得分: 2
class SavedStdOut(io.StringIO):
def __init__(self, stdout):
super().__init__()
self.stdout = stdout
def write(self, s: str):
self.stdout.write(s)
return super().write(s)
foo = SavedStdOut(sys.stdout)
foo.write('Hello\n') # Hello
print('Buffer:', foo.getvalue()) # Buffer: Hello
import io
import sys
import time
import traceback
class SavedStdOut(io.StringIO):
def __init__(self, stdout):
super().__init__()
self.stdout = stdout
def write(self, s: str):
self.stdout.write(s)
return super().write(s)
def return_std(func):
def wrapper(*args, **kwargs):
sys.stdout = buffer = SavedStdOut(sys.stdout)
try:
func(*args, **kwargs)
except:
print(traceback.format_exc())
finally:
sys.stdout = buffer.stdout
body = buffer.getvalue()
buffer.close()
return body
return wrapper
@return_std
def some_useful_function():
print('so this line is executed at ' + time.strftime('%X'))
time.sleep(5)
print('program execute at ' + time.strftime('%X'))
std_of_some_useful_function = some_useful_function()
print('saved stdout:', std_of_some_useful_function)
print('but we can not know if it succeeded or failed before ' + time.strftime('%X'))
Output:
program execute at 03:52:01
so this line is executed at 03:52:01 # Printed as soon as print() is called
saved stdout: so this line is executed at 03:52:01
but we can not know if it succeeded or failed before 03:52:06
英文:
You can create a subclass of io.StringIO and override the write()
method so that it writes to a saved version of sys.stdout
aswell as writing to it's internal buffer
class SavedStdOut(io.StringIO):
def __init__(self, stdout):
super().__init__()
self.stdout = stdout
def write(self, s: str):
self.stdout.write(s)
return super().write(s)
The class then writes to the passed file and saves the written data
foo = SavedStdOut(sys.stdout)
foo.write('Hello\n') # Hello
print('Buffer:', foo.getvalue()) # Buffer: Hello
A complete example
import io
import sys
import time
import traceback
class SavedStdOut(io.StringIO):
def __init__(self, stdout):
super().__init__()
self.stdout = stdout
def write(self, s: str):
self.stdout.write(s)
return super().write(s)
def return_std(func):
def wrapper(*args, **kwargs):
sys.stdout = buffer = SavedStdOut(sys.stdout)
try:
func(*args, **kwargs)
except:
print(traceback.format_exc())
finally:
sys.stdout = buffer.stdout
body = buffer.getvalue()
buffer.close()
return body
return wrapper
@return_std
def some_useful_function():
print('so this line is executed at ' + time.strftime('%X'))
time.sleep(5)
print('program execute at ' + time.strftime('%X'))
std_of_some_useful_function = some_useful_function()
print('saved stdout:', std_of_some_useful_function)
print('but we can not know if it succeeded or failed before ' + time.strftime('%X'))
Output:
program execute at 03:52:01
so this line is executed at 03:52:01 # Printed as soon as print() is called
saved stdout: so this line is executed at 03:52:01
but we can not know if it succeeded or failed before 03:52:06
答案2
得分: 1
Create a my_print
class with __call__
operator and overwrite the builtins.print
method with your class like this.
class MyPrint():
def __init__(self):
self.__buffer = io.StringIO()
self.__old_print = __builtin__.print
def getvalue(self):
return self.__buffer.getvalue()
def close(self):
self.__buffer.close()
__builtin__.print = self.__old_print
def __call__(self, *args, **kwargs):
self.__buffer.write(args[0])
self.__old_print(*args, **kwargs)
Use the return_std
decorator to capture the standard output of a function like this:
def return_std(func):
def wrapper(*args, **kwargs):
my_print = MyPrint()
__builtin__.print = my_print
try:
func(*args, **kwargs)
except:
print(traceback.format_exc())
finally:
body = my_print.getvalue()
my_print.close()
return body
return wrapper
@return_std
def some_useful_function():
print('so this line is executed at ' + time.strftime('%X'))
time.sleep(1)
print('program execute at ' + time.strftime('%X'))
std_of_some_useful_function = some_useful_function()
print(std_of_some_useful_function)
print('but we can not know if it succeeded or failed before ' + time.strftime('%X'))
This code allows you to capture and analyze the standard output of a function.
英文:
Not convinced that whatever you are trying to do is a good idea but you can do it like so.
Create a my_print
class with __call__
operator and overwrite the builtins.print
method with your class like this.
class MyPrint():
def __init__(self):
self.__buffer = io.StringIO()
self.__old_print = __builtin__.print
def getvalue(self):
return self.__buffer.getvalue()
def close(self):
self.__buffer.close()
__builtin__.print = self.__old_print
def __call__(self, *args, **kwargs):
self.__buffer.write(args[0])
self.__old_print(*args, **kwargs)
def return_std(func):
def wrapper(*args, **kwargs):
my_print = MyPrint()
__builtin__.print = my_print
try:
func(*args, **kwargs)
except:
print(traceback.format_exc())
finally:
body = my_print.getvalue()
my_print.close()
return body
return wrapper
@return_std
def some_useful_function():
print('so this line is executed at ' + time.strftime('%X'))
time.sleep(1)
print('program execute at ' + time.strftime('%X'))
std_of_some_useful_function = some_useful_function()
print(std_of_some_useful_function)
print('but we can not know if it succeeded or failed before ' + time.strftime('%X'))
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论