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

时间:2010-10-11 12:38:17

标签: python printing exec

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

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

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

0
1
2

问候并感谢,

7 个答案:

答案 0 :(得分:37)

我有与Frédéric相同的想法,但我写了一个上下文管理器来处理替换stdout:

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()

答案 1 :(得分:7)

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

    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()

答案 2 :(得分:4)

这是@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())

答案 3 :(得分:2)

这是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

答案 4 :(得分:1)

类似的东西:

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

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

答案 5 :(得分:0)

Python 3:将exec的输出转换为变量

import io, sys
print(sys.version)

#keep a named handle on the prior stdout 
old_stdout = sys.stdout 
#keep a named handle on io.StringIO() buffer 
new_stdout = io.StringIO() 
#Redirect python stdout into the builtin io.StringIO() buffer 
sys.stdout = new_stdout 

#variable contains python code referencing external memory
mycode = """print( local_variable + 5 )""" 

local_variable = 2
exec(mycode)

#stdout from mycode is read into a variable
result = sys.stdout.getvalue().strip()

#put stdout back to normal 
sys.stdout = old_stdout 
 
print("result of mycode is: '" + str(result) + "'") 

打印:

3.4.8
result of mycode is: '7'

还要提醒您,Python exec(...)是有害的,也是有害的,因为1.它使您的代码变成不可读的goto-spaghetti。 2.介绍最终用户代码注入的机会,并且3.由于exec是由线程组成的,并且线程不好,因此将异常stacktrace置于混乱状态。

答案 6 :(得分:0)

您可以将 exec 与 eval 结合使用以获得列表形式的输出:

ExecString('i = [0,1,2]');
println(EvalStr('[j for j in i]'));