python:在exec语句中获取打印输出

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3906232/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 13:18:01  来源:igfitidea点击:

python: get the print output in an exec statement

pythonprintingexec

提问by user462794

I've got a little problem. Here is my code:

我有一个小问题。这是我的代码:

code = """
i = [0,1,2]
for j in i :
    print j
"""
result = exec(code)

How could I get the things that print outputed? How can I get something like:

我怎么能得到打印输出的东西?我怎样才能得到类似的东西:

0
1
2

Regards and thanks,

问候和感谢,

采纳答案by Jochen Ritzel

I had the same idea as Frédéric, but i wrote a context manager to handle replacing stdout:

我和 Frédéric 有同样的想法,但我写了一个上下文管理器来处理替换标准输出:

import sys
import StringIO
import contextlib

@contextlib.contextmanager
def stdoutIO(stdout=None):
    old = sys.stdout
    if stdout is None:
        stdout = StringIO.StringIO()
    sys.stdout = stdout
    yield stdout
    sys.stdout = old

code = """
i = [0,1,2]
for j in i :
    print j
"""
with stdoutIO() as s:
    exec code

print "out:", s.getvalue()

回答by Blam

Something like:

就像是:

 codeproc = subprocess.Popen(code, stdout=subprocess.PIPE)
 print(codeproc.stdout.read())

should execute the code in a different process and pipe the output back to your main program via codeproc.stdout. But I've not personally used it so if there's something I've done wrong feel free to point it out :P

应该在不同的进程中执行代码并将输出通过管道返回到主程序codeproc.stdout。但我没有亲自使用它,所以如果我做错了什么,请随时指出:P

回答by Frédéric Hamidi

You can redirect the standard output to a string for the duration of the exec call:

您可以在 exec 调用期间将标准输出重定向到字符串:

    code = """
i = [0,1,2]
for j in i :
print j
"""

from cStringIO import StringIO
old_stdout = sys.stdout
redirected_output = sys.stdout = StringIO()
exec(code)
sys.stdout = old_stdout

print redirected_output.getvalue()

回答by Ilya V. Schurov

Here is Py3-friendly version of @Jochen's answer. I also added try-exceptclause to recover in case of errors in the code.

这是@Jochen 答案的 Py3 友好版本。我还添加了try-except子句以在code.

import sys
from io import StringIO
import contextlib

@contextlib.contextmanager
def stdoutIO(stdout=None):
    old = sys.stdout
    if stdout is None:
        stdout = StringIO()
    sys.stdout = stdout
    yield stdout
    sys.stdout = old

code = """
i = [0,1,2]
for j in i :
    print(j)
"""
with stdoutIO() as s:
    try:
        exec(code)
    except:
        print("Something wrong with the code")
print("out:", s.getvalue())

回答by sergzach

Here is a small correction of Frédéric's answer. We need to handle a possible exception in exec()to return back normal stdout. Otherwise we could not see farther printoutputs:

这是 Frédéric 答案的一个小更正。我们需要处理一个可能的异常exec()以返回正常stdout。否则我们看不到更远的print输出:

code = """
i = [0,1,2]
for j in i :
print j
"""

from cStringIO import StringIO
old_stdout = sys.stdout
redirected_output = sys.stdout = StringIO()
try:
    exec(code)
except:
    raise 
finally: # !
    sys.stdout = old_stdout # !

print redirected_output.getvalue()
...
print 'Hello, World!' # now we see it in case of the exception above