python: получить вывод на печать в операторе exec - PullRequest
26 голосов
/ 11 октября 2010

У меня маленькая проблема. Вот мой код:

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

Как я могу получить вещи, которые печатаются? Как я могу получить что-то вроде:

0
1
2

С уважением и благодарностью

Ответы [ 5 ]

37 голосов
/ 11 октября 2010

У меня была та же идея, что и у Фредерика, но я написал менеджер контекста для обработки замены 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()
7 голосов
/ 11 октября 2010

Вы можете перенаправить стандартный вывод в строку на время вызова 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()
4 голосов
/ 12 января 2017

Вот Py3-дружественная версия ответа @ Jochen.Я также добавил условие 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())
2 голосов
/ 16 ноября 2017

Вот небольшое исправление ответа Фредерика. Нам нужно обработать возможное исключение в 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
1 голос
/ 11 октября 2010

Что-то вроде:

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

должно выполнить код в другом процессе и передать вывод обратно в вашу основную программу через codeproc.stdout.Но я не использовал это лично, поэтому, если я что-то сделал не так, не стесняйтесь указывать: P

...